Инструкция с LEA и MOV приводит к одному и тому же результату - почему?

В целях тестирования я написал код сборки x86:

lea  ebx, [esi]

Я изменил строку и написал:

mov  ebx, esi

и программа делает то же самое. Почему?

В esi хранится адрес строки. В первой строке я сохранил адрес адреса строки, верно? А во 2 строке он должен хранить только адрес строки.

Здесь Амит Сингх Томар написал, что

 mov eax ,var == lea eax [var]

и когда я прочитал и применил это к моему делу, я был немного сбит с толку.

редактировать: я также пытаюсь перевести эти две строки выше в код псевдо-C, и это выглядит так (я предполагаю, что ebx и esi являются указателями):

 (1st line with lea):

 unknownType *ebx = &(*esi)  // since the brackets mean dereferencing, 
                             // I use the dereferencing operator * 
                             // and since lea is equal to the 
                             // address of operator, I came to this result


 (2nd line with mov):
 unknownType *ebx; 
 ebx = esi ;                 // in the second case, ebx would point also 
                             // to the address of the string

Но это было бы не то же самое, верно?


person user3097712    schedule 17.12.2015    source источник
comment
Потому что они одинаковы. Они такие же и в вашем псевдо-C. & съедает *, так что &*esi это всего лишь esi.   -  person Jester    schedule 18.12.2015
comment
Основная причина, по которой вы обычно используете LEA вместо MOV, заключается в том, что вы можете выполнять некоторые арифметические функции, используя LEA, которые потребуют дополнительных инструкций, используя MOV.   -  person David Hoelzer    schedule 18.12.2015


Ответы (2)


В оригинальном 8088/8086 я не думаю, что была какая-то разница, и я задавался тем же вопросом. Может быть, один был на байт короче или выполнялся на цикл меньше.

Однако, начиная с 80386, эффективные режимы адресации расширены.

mov  ebx, 8[esi*4]

При этом lea значительно полезнее, поскольку нет способа сделать это с помощью одной инструкции.

mov  ebx, 8+ esi * 4      // illegal

Тем не менее, это совершенно правильно и полезно:

lea  ebx, 8[esi * 4]      // useful and legal
person wallyk    schedule 17.12.2015
comment
Хотя 8086 был более ограниченным, он также имел другие режимы адресации, помимо одного регистра. - person Jester; 18.12.2015

Ваш перевод на псевдо-C правильный (при условии, что unknownType *esi; над показанным кодом). Чего вы не поняли, так это, опять же на псевдо-C, что

&(*x) == x

для всех допустимых указателей x. Вы не взяли адрес адреса строки; вы взяли только адрес строки.

person zwol    schedule 17.12.2015
comment
Я почему-то чувствую, что это упускает суть фактического вопроса ... Если я неправильно понимаю ОП, реальный вопрос касается различий между LEA и MOV, а не указателей в коде C. Я могу ошибаться, конечно. - person David Hoelzer; 18.12.2015