Изначально возник другой вопрос: почему же всё-таки у LEA второй операнд в скобках (синтаксис MASM&TASM не обсуждается!). Для ответа заглянул в доку Интела, ведь хочется же понять, чем отличается допустим: mov EAX,12345678 от lea EAX,[12345678] Кажется, начал понимать, когда нашел важное отличие. У MOV в таком раскладе не может быть сгенерировано #UD, а у LEA может: Protected Mode Exceptions #UD If source operand is not a memory location. Real-Address Mode Exceptions #UD If source operand is not a memory location. Virtual-8086 Mode Exceptions #UD If source operand is not a memory location. Compatibility Mode Exceptions Same exceptions as in Protected Mode. 64-Bit Mode Exceptions #UD If source operand is not a memory location. Теперь вот сижу и думаю, что же такое "is not a memory location". По каким признакам определяется это "memory location"?
Это значит, что в байте ModeR/M поле Mod не может быть равно 11b (регистр-регистр), т.е. lea eax,[eax] -> 8D 00 -> Ok lea eax, eax -> 8D C0 -> #UD
leo, спасибо! Тогда опять не понимаю, почему Интел решили заскобить второй операнд LEA? То есть я, конечно, понимаю логику "все указатели в квадратных скобках", но зачем вообще было привязывать такое логическое действие к понятию указатель? Ведь получается, что LEA просто вычислитель значений... Причём тут указатель?
LEA это "просто вычислитель" значений, но не любых, а только тех, которые допустимы в кодировках байтов ModR/M и SIB для вычисления адресов операндов памяти. Соответственно в процессорах LEA может выполняться не на АЛУ, а в блоках вычисления адреса (может, но не обязано - тут уж как разработчики камней решат) Использование скобок - это соглашения асма и его наречий, а Интелу пофиг - он только с кодировками ModR/M и SIB дело имеет - если некий асм будет компилить "lea eax,eax" в "8D 00", а не в "8D C0", то все будет шито-крыто )