2015-09-05 62 views
2

TL; DR

[memloc]是指值還是地址?如果它是指任何一個,那麼爲什麼它的值都是的地址? (見下面的代碼,行4和5)NASM - 這是地址,價值?

全部問題...

對不起,長的問題。 我很困惑在NASM標籤解引用。以這個例子:

01| section .text 
02| ; exiting the program with exit code "15" 
03| 
04| mov  [memloc], 15 ; move 15 into memloc 
05| push [memloc]  ; push memloc on stack 
06| mov  eax, 1  ; prepare exit syscall 
07| call kernel  ; invoke syscall 
08| 
09| section .data 
10| memloc: dd 0 ; let's say this is at address 0x1234 

當我運行它時,它退出代碼爲15.它的工作原理!
...但是爲什麼?不應該memlock沒有大括號第4行,其中push大概預計目的地?

例如:
在線路的mov指令04值15移動到memloc的ADDRESS:

mov  [memloc], 15 ; move 15 into mem @memloc 

但線05推儲存在memloc到堆棧的值:

push [memloc]  ; push value @memloc on stack 

那麼,是[memloc]的值(15)還是地址(0x1234)?理論上如果你mov memloc, 15取而代之會發生什麼?

預先感謝您。

+0

如果操作對待它的操作數不同根據您是否把括號圍繞它,然後我猜測我的問題是'機器代碼如何區分地址和值?' –

+0

它沒有,這是你必須在它周圍加上括號的原因。 – Siguza

回答

2

有超過1版mov(這之後,它已經被你的代碼的第10行設置你不能改變)指令。如果編譯器(NASM)看到周圍memloc方括號它產生的mov一種形式,如果你的編譯器不看到周圍memloc方括號它產生的mov另一種形式。

考慮以下說明:

mov edx, memloc 
mov edx, [memloc] 
mov [memloc], edx 

他們都mov /從同一目的地/源寄存器EDX但是編譯器(NASM)會產生這些指令完全不同的操作碼。

第一個mov用5個字節0xBA編碼,?,?,?,?
第二個mov用6字節0x8B,0x15,?,?,?,?
第三個mov用6字節0x89,0x15,?,?,?,?

The 4 代表由NASM分配的memloc的地址。
使用在你的問題的示例地址(0×1234),這將成爲:

的第一mov編碼有5個字節0xBA,0x34,0×12,0x00時,0×00
的第二mov編碼有6個字節0x8B,爲0x15 ,0x34,0×12,0×00,0×00
第三mov編有6個字節0x89上,爲0x15,0x34,0×12,0×00,0×00

+0

這絕對是導致我困惑的原因。當他們真正改變操作時,我認爲括號表示參考文獻中的變化。謝謝您的回答! –

1

如果您改爲mov memloc, 15,理論上會發生什麼?

NASM不會除此之外,因爲你不能移動立即值(15)到另一個immendiate值(memloc)。

在線04移動時的值15至memloc的地址mov指令:

指令在管線4不改變memloc的地址。
就像第5行,它使用存儲在memloc的值。

那麼,是[memloc]值(15)還是地址(0x1234)?

[memloc]是價值15
memloc是地址爲0x1234

+0

好的,但是'mov'指令必須知道它在哪裏放置信息的_address_。就像我告訴你將郵件放入郵箱中一樣,您需要知道郵寄地址。我無法向您發送包裝箱中的郵件,希望您能夠神奇地發現它,對嗎? (假設沒有郵件上有地址,lol) –

+1

@ JamesM.Lay有超過1個版本的'mov'指令。如果編譯器(NASM)在* memloc *的周圍看到方括號,它會生成一種形式的「mov」,如果編譯器在* memloc *周圍沒有看到方括號,則會生成另一種形式的「mov」。 –

+0

@ user3144770所以,當你'mov [mem],eax'時,地址仍然被傳遞,但是對於需要偏移的操作碼?因此,不應將'mem'視爲「查找並替換」目標,我應該將它看作更像C指針,其中'mov [mem],eax'就像'* mem = eax'和'push [mem] '就像'push(* mem)'? –