Я изучаю Ассемблер и добираюсь до такой степени, что на самом деле понятия не имею о различии между [variable]
и variable
. Как говорят в учебниках, оба являются указателями, так в чем же смысл этого? И почему мне нужно использовать type Identifier
до []
?
мой ассемблер: nasm x86_64 running on Linux--> Ubuntu
Разница сборки между [var] и var
Ответ 1
В x86 синтаксис Intel [expression]
означает содержимое памяти по адресу expression
.
expression
без скобок зависит от используемого вами ассемблера.
NASM:
mov eax,variable ; moves address of variable into eax
lea eax,[variable] ; equivalent to the previous one (LEA is exception)
mov eax,[variable] ; moves content of variable into eax
MASM (TASM):
mov eax,variable ; content of variable (for lazy programmers)
mov eax,OFFSET variable ; address of variable
lea eax,[variable] ; address of variable
mov eax,[variable] ; content of variable
GAS (синтаксис AT & T):.. Я не собираюсь беспокоиться, это не синтаксис Intel.
Во всех случаях variable
является псевдонимом для символа, обозначающего особое место в памяти, где появилась метка. Итак:
variable1 db 41
variable2 dw 41
label1:
выводит три символа в таблицу символов, variable1
, variable2
и label1
.
Когда вы используете какой-либо из них в коде, например mov eax,<symbol>
, он не имеет информации о том, был ли он определен db
или dw
или как метка, поэтому он не даст вам никаких предупреждений, когда вы делаете mov [variable1],ebx
(переписывая 3 байта за определенный первый байт).
Это просто адрес в памяти.
Идентификатор типа должен использоваться в большинстве ассемблеров только, когда тип не может быть выведен из самих операндов.
mov [ebx],eax ; obviously 32 bits are stored, because eax is 32b wide
mov [ebx],1 ; ERROR: how "wide" is that immediate value 1?
mov [ebx],WORD 1 ; NASM syntax (16 bit value, storing two bytes)
mov WORD [ebx],1 ; NASM syntax (16 bit value, storing two bytes)
mov WORD PTR [ebx],1 ; MASM/TASM syntax
Ответ 2
Небольшой пример с использованием регистров и указателей:
mov eax, 10
означает: переместите в регистр EAX значение 10. В этом случае EAX используется только для хранения чего-либо. Все, что содержит EAX, не имеет никакого значения для программиста, так как оно все равно будет стерто.
mov [eax], 10
означает: переместите значение 10 в адрес, сохраненный в регистре EAX. В этом случае значение, хранящееся в EAX, имеет для нас большое значение, так как это указатель, что означает, что нам нужно перейти в регистр EAX и посмотреть, что содержит, то мы используем это значение как адрес для доступа.
При использовании указателя необходимо два шага:
-
Перейдите в EAX и посмотрите, какое значение оно содержит (например, EAX = 0xBABA);
-
Перейдите к адресу, указанному EAX (в нашем случае 0xBABA) и напишите 10. В нем
Конечно, указатели не обязательно используются с регистрами, этот маленький пример - это просто объяснить, как это работает.
Ответ 3
Поскольку вы уже знаете С++, я собираюсь ответить, показывая вам, что такое C-эквиваленты этих выражений.
Когда вы пишете
[variable]
в сборке, что эквивалентно
*variable
в C. То есть, обработайте variable
как указатель и разыщите этот указатель - получите значение, на которое указывает указатель.
Аналогично, "идентификаторы типов" похожи на то, что они переводят указатель на другой тип:
ASM:
dword ptr [variable]
C:
*((uint32_t*) variable)
ASM:
word ptr [variable]
C:
*((uint16_t*) variable)
Надеюсь, это поможет вам понять смысл этих выражений.
(этот раздел относится к добавлению, которое с тех пор было удалено из исходного вопроса)
Я не совсем уверен, в чем проблема, с которой вы сталкиваетесь с "преобразованием в ascii", но я подозреваю, что вы просто смущены тем, как визуально визуализируется на выходе или что-то в этом роде.
Например, если у вас есть такой код:
myInteger db 41
mov AL, byte ptr [myInteger]
mov
скопирует значение 41
из памяти в регистр AL
. Число 41
является представлением ascii для символа )
, но это ничего не меняет. Является ли значение интерпретируется как символ ascii или как целое число до вас, потому что они имеют одинаковое значение.