Почему вы должны разыменовывать метку данных, чтобы что-то хранить там: Сборка 8086 FASM

Рассмотрим следующий пример:

mov al, [variable1]

Это имеет смысл, так как вы сохраняете в регистре все содержимое (тем самым разыменовывая его) переменной1.

Теперь рассмотрим этот пример:

mov dword L6, 1

Это неправильно; правильная форма

mov dword [L6], 1

Если мы перемещаем 1 в память, я должен сказать, что он должен храниться по этому адресу, а не по содержимому. Скажем, вы говорите кому-то пойти в определенное место на вечеринку, вы дали бы им адрес вечеринки, а не людей там.

Итак, почему это?


person Duarte Arribas    schedule 08.04.2020    source источник
comment
Разыменование означает, что вы получаете доступ к содержимому. Это либо чтение из него, либо запись в него. Вы не хотите писать (менять) адрес, что невозможно, вы хотите писать (менять) содержание.   -  person ecm    schedule 08.04.2020
comment
x86 не имеет адресации данных, косвенно относящейся к памяти. Это разница между уровнями косвенности 0 и 1 по сравнению с адресом символа как непосредственным, а не 1 против 2.   -  person Peter Cordes    schedule 08.04.2020
comment
если я думаю о mov как о записи, это имеет гораздо больше смысла. Могу ли я думать о mov как о записи вместо перемещения?   -  person Duarte Arribas    schedule 08.04.2020
comment
Да. mov просто копирует исходный операнд в целевой операнд. Вот почему пункт назначения должен указывать на память или регистр.   -  person Peter Cordes    schedule 08.04.2020


Ответы (1)


x86 не имеет адресации данных, косвенно относящейся к памяти. Это разница между уровнями косвенности 0 и 1 по сравнению с прямым адресом символа, а не между уровнями 1 и 2.

В отличие от C, в синтаксисе FASM (и NASM) упоминание имени простого символа является адресом в качестве значения.

например mov eax, symbol устанавливает EAX = адрес, по которому вы помещаете эту метку, с помощью инструкции mov eax, imm32, а не загрузки из памяти.

Конечно, mov symbol, eax не может работать, потому что непосредственная константа не может быть адресатом, а может быть только режим адресации [disp32].

если я думаю о mov как о записи, это имеет гораздо больше смысла. Могу ли я думать о mov как о записи вместо «перемещение»?

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

(Конечно, у вас не может быть и src, и dst памяти для одной инструкции mov; существуют разные формы для разных видов операндов.)


Символ asm в FASM и NASM работает примерно так же, как C char arr[].

Вы не можете сделать arr = x; - ассемблерным эквивалентом является mov arr, al, что также недопустимо (в синтаксисе FASM и NASM).

Но вы можете сделать *arr = x;, что на ассемблере mov [arr], al


К вашему сведению: синтаксис MASM отличается: вместо символов, работающих в качестве заполнителя для числа во всех контекстах, mov sym, al является хранилищем, таким же, как mov [sym], al, а скобки являются необязательными и бессмысленными без регистра.

Если вы видите какие-либо примеры MASM или вывод GCC/clang .intel_syntax noprefix; вот что происходит.

person Peter Cordes    schedule 08.04.2020