2017-10-21 104 views
1

這裏是我的代碼:對於X86_64 linux組裝中標籤的使用感到困惑:爲什麼我們應該寫mov [digit],al,而不是mov digit,al?

section .data 
    digit db 0,10 

section .text 
    global _start 
_start: 

    call _printRAXDigit 

    mov rax, 60 
    mov rdx, 0 
    syscall 


_printRAXDigit: 
    add rax, 48 
    mov [digit], al 

    mov rax, 1 
    mov rdi, 1 
    mov rsi, digit 
    mov rdx, 2 
    syscall 
    ret 

我有一個關於[digit]digit之間的差異問題。

我已經瞭解到,標籤(如代碼中的數字)表示數據的內存地址,操作符「[]」的作用就像取消引用指針的東西,因此它會加載值標籤指向目的地。

例如,mov rax, [digit]將在數據的第一個元素扔0到rax寄存器,因爲數字點(在此情況下,整數0)。

然而,在我的代碼,它工作時,我寫mov [digit], al,這意味着「加載存儲在al到內存地址價值」,但我不知道爲什麼我們要在此用「[]」案件。 mov的第一個參數必須是目的地(如寄存器或內存地址),所以我認爲它應該是mov digit, al而不是mov [digit], al。對於我來說,爲什麼我們使用一個值從另一個地方獲取值,而不是使用內存地址來獲取值。

這就是我所有的問題。請給我任何迴應,關於我的思維錯誤或對標籤概念的任何更正。

+0

'digit' *是*地址。但它也是一個數字。你需要告訴彙編器如何解釋它。 –

+0

你是什麼意思,「數字是一個地址,但它也是一個數字。」,你可以給任何具體的例子,以便我可以更多地瞭解,謝謝 –

+0

0是一個地址。這是一個數字。 3是地址。這是一個數字。 27是地址。這是一個數字。 252是地址。這是一個數字。 –

回答

5

在NASM語法(有裝配使用不同的符號,如MASM/TASM use a different flavor of Intel syntax和氣體使用AT&T syntax)以下的x86指令......

mov esi, someAddress 
mov esi, [someAddress] 
mov [someAddress], esi 
mov someAddress, esi ; see below 

...(將)具有以下含義:

mov esi, someAddress 

將表示存儲someAddress的地址的數字寫入寄存器esi。所以如果someAddress存儲在地址1234處,則值1234被寫入esi

mov esi, [someAddress] 

將內存的內容寫入esi。因此,如果someAddress存儲在地址1234並且存儲在地址1234的值是5678,則值5678被寫入esi

您可能還會說:變量someAddress(通常變量通常只是某個地址處的內存內容)的值被寫入esi寄存器。

mov [someAddress], esi 

寫的esi到內存地址someAddress內容。

您可能還會說:將esi的值寫入變量someAddress

mov someAddress, esi 

平均:更改常數代表地址someAddressesi

所以,如果someAddress位於地址1234和esi包含值5678的指令將意味着:

變化的數學常數1234的方式,1234 = 5678之後的變化。

這當然是愚蠢的,因爲數學常數1234和5678永遠不會相等。出於這個原因,x86 CPU沒有這樣的指令。

(有些CPU有類似的指令,例如在SPARC CPU上指令給零寄存器賦值(也就是說:「給常數零賦一個值」),如果你只想使用指令副作用 - 例如設置標誌 - 但您對結果本身不感興趣。)

+1

你稱之爲「正常」的理性語法是NASM風格。 'mov esi,[digit]'和'mov esi,digit'都是加載和'mov esi,offset digit'的mov-immediate是MASM/TASM風格。 [MASM甚至在'mov eax中忽略括號,[constant]爲'='常量(如equ)!](https://stackoverflow.com/a/25130189/224132)。顯然有些人認爲這是正常的,所以你可能需要澄清。 (我根據Linux標籤和問題中的文字標記了問題'[nasm]',描述了一些事情做了什麼) –

+0

@PeterCordes我使用了「normal」這個詞,因爲我通常使用AT&T風格的彙編器('movl $ someAddress ,%esi')。我並不知道NASM和MASM之間是有區別的。 –

+0

啊,那麼你要找的術語是「英特爾語法」。 NASM和MASM都是英特爾語法的風格。我最近用一些關於NASM和MASM語法的東西更新了[intel-syntax tag wiki](https://stackoverflow.com/tags/intel-syntax/info)。請注意,GAS'.intel_syntax noprefix'類似於MASM,不像NASM。 (例如'mov eax,symbol'是一個負載。) –

相關問題