2016-07-31 2 views
0

При использовании как MOV и LEA инструкции по сборке, что делает это на самом деле означает, когда кто-то пишет:Сборочный регистр Арифметика?

mov DWORD PTR [esp+4], 0x80484c 
    lea eax,[ebp-40] 

В частности, когда они пишут информацию в скобках []. Я знаю, что lea перемещает адреса и перемещает контент mov, но когда они вычисляют адреса в lea или mov, как это работает? Это то же самое, что и арифметика указателя в C?

+3

'это то же самое, как арифметики указателей в C' Нет, это не так. Полноценный ответ можно найти в любой достойной документации/книге сборки x86 и свободно доступной. –

+0

Имейте в виду, что в 'lea' нет реального доступа к памяти: он просто вычисляет адрес операнда и сохраняет его. Компиляторы иногда используют его для выполнения арифметики без знака - хотя и не в этом конкретном случае. –

+0

Не только подробные ответы могут быть найдены в сборке, вы можете найти множество очень полных и ясных ответов здесь, чтобы получить быстрый поиск. –

ответ

4

lea не Переместить адреса, он вычисляет эффективный адрес и сохраняет полученный адрес в регистр назначения. Вычисления адресов выполняются на машинных языках с регулярной арифметикой, а не с арифметикой с указателем.

lea eax,[ebp-40] 

вычитает 40 от значения в регистре ebp и сохраняет результат в регистре eax.

mov DWORD PTR [esp+4], 0x80484c 

Вычисляет адрес назначения пути добавления к 4 значению, содержащемуся в регистре esp и сохраняет значение 0x80484c, целого число 8407116, как 32-битовое целое число, занимающее 4 байт по этому адресу, младшие байты первым.

2

lea просто вычисляет выражение и сохраняет его в переменной. На самом деле он ничего не делает с адресами памяти или памяти, даже через него называется «загружаемый эффективный адрес».

Например, lea eax,[ebp-40]eax = ebp - 40.

Он может быть использован для вычисления выражений, которые бы в противном случае потребуется несколько инструкций, например:

lea eax, [8 * eax + ebx + 10] 

вычисляет eax = 8 * eax + ebx + 10 с одной инструкцией.

С другой стороны, mov, при использовании с [...], считывает/записывает что-то из памяти в память, так что это похоже на использование указателей C.

mov DWORD PTR [esp+4], 0x80484c 

Это экономит 32-битное целое число без знака (DWORD) значение 0x80484c к ячейке памяти esp + 4, то есть такой же, как следующий псевдо-C:?

*((uint32_t*)(esp + 4)) = 0x80484c; 
+0

Итак, можете ли вы сказать, что каждый регистр начинается без каких-либо бит/байтов в нем, и для перемещения значений в эти регистры вам нужно добавить байты в эти регистры? Так что, если бы я хотел переместить 32-битный int в регистр EAX, я должен был бы сказать: mov DWORD PTR [EAX + 4], (32 бит int)? –

+0

@JohnConradGeenty Нет.Регистры CPU - это только внутренние переменные CPU. Например, 'eax' является 32-битным регистром и всегда будет содержать 32-битное значение, точно 32-битную переменную. (Google о регистрах сборки X86, чтобы узнать больше.) –

+0

@JohnConradGeenty Чтобы переместить значение в регистр, вы используете 'mov eax, (32-битное значение)'. Я отредактировал свой ответ, чтобы упомянуть, что только с '[...]' будет 'mov' доступ к памяти. –