2013-05-17 2 views
1

Я новичок в сборке, и я использую MASM. Я вижу эти строки кода и интересно, что разница междуРазница между push myVar, push [myVar] и push OFFSET myVar

a) push myVar 

b) push [myVar] 

c) push OFFSET myVar 

Как я знаю, если они толкают значение или адрес MYVAR Спасибо!

С наилучшими пожеланиями, Благодаря

ответ

2

push myVar просто подталкивая вар на стеке.

push [myVar] является разыменование вашего var. если myVar является указателем, этот код будет вызывать значение по адресу в стеке.

Я не уверен в последнем, но кажется, что он обратный, push OFFSET myVar толкает адрес myVar в стек.

+1

_ "Если myVar является указателем, этот код будет вызывать значение по адресу в стеке." _ Фактически он будет делать то же самое, что и в первом случае (нажмите значение 'myVar'). – Michael

+0

Хорошо. Значит, это означает, что [] не имеет значения. Правильно? –

+0

№ «push [var] - нажмите 4 байта по адресу var в стек». Это означает, что если var не является указателем, это может привести к неопределенному поведению. –

2

Это зависит от того, какой ассемблер вы используете. С помощью MASM/TASM первые два варианта делают то же самое (нажмите на значение myVar на стек), а третий вариант выталкивает адрес myVar в стек (в сегментированном режиме, который будет смещением в текущем сегменте).

Другими словами, MASM/TASM предполагает, что вы хотите разыменовать эффективный адрес переменной, даже если вы пишете ее без скобок.Если вы имели непосредственное значение в качестве адреса/операнда было бы разницы, хотя:

pushd 0    ; push the dword value 0 onto the stack 
push dword ptr [0] ; push the dword at address 0 onto the stack 
        ; will likely crash your program 

И точно также для регистровых операндов:

push eax    ; push the value of eax onto the stack 
push dword ptr [eax] ; push the value at the address that eax points to 

С NASM вы бы написать первые два варианты как

push dword [myVar] ; assuming a dword variable 

И третий, как

push myVar 
1

Допустим, у нас есть data сегмент объявлен как это:

.data 
myVar DWORD 1, 5, 9 

Без []

Теперь давайте это в code разделе:

.code 
mov eax, myVar 

Если мы теперь взгляните на регистры (через отладчик, для примера ле), мы можем увидеть что-то вроде этого:

EAX = 00000001 

С []

Мы можем использовать скобки в качестве оператора разыменования, как мы будем использовать * в C, так что если мы теперь изменить линию к этому:

mov eax, [myVar] 

мы получаем:

EAX = 00000001 

hmm ... такой же.

Но теперь мы можем думать, ха !, если положить адрес смещение myVar, я должен получить следующее значение из MYVAR «массива»:

mov eax, [myVar + 4] ; +4, because we have a DWORD (4 Bytes) 

и результат есть:

EAX = 00000005 

Это работает! Но что, если я сделаю то же самое без скобок?

mov eax, myVar + 4 
EAX = 00000005 

Хммм, такой же предмет! Поэтому не должно быть разницы в использовании двух обозначений. Таким образом, они совершенно эквивалентны.

Смежные вопросы