2015-12-11 47 views
0
extern printf    ; the C function, to be called 

SECTION .data    ; Data section, initialized variables 
a: dd 5      ; int a=5; 
fmt: db "a=%d, eax=%d",10,0 ; The printf format, "\n",'0' 

SECTION .text    ; Code section. 

global main     ; the standard gcc entry point 
main:      ; the program label for the entry point 

    push ebp     ; calling convention 
    mov ebp, esp 

    mov eax, [a]    ; put a from store into register 
    add eax, 2    ; a+2 
    push eax     ; value of a+2 
    push dword [a]   ; value of variable a 
    push dword fmt   ; address of ctrl string 
    call printf    ; Call C function 
    add esp, 12    ; pop stack 3 push times 4 bytes 

    mov esp, ebp    ; returning convention 
    pop ebp     ; same as "leave" op 

    mov eax,0     ; normal (no error) return value 
    ret      ; return 

我感到有點困惑。我知道dd聲明瞭一個4字節的值並在其中存儲了5個字節。在彙編中存儲eax中的值

1)然後mov eax, [a]將它存儲在eax寄存器中。但不是AX只有2個字節的寄存器。它如何存儲一個4字節的值?

2)fmt: db "a=%d, eax=%d",10,0我知道fmt是一個位置名稱,db聲明瞭一個字節,但接下來的代碼是做什麼的?

+0

E代表擴展。 EAX存儲32位。 – Dzenly

+0

關於#2,我建議您查看有關printf函數如何與格式字符串一起工作的信息。 –

回答

1

術語:從內存中讀取(add eax, [a])是一個「負載」。寫入內存是一個「商店」(mov [a], eax)。

A dd指令並不「存儲」在這個意義上,但。當程序啓動時,數據已經存在。使用「puts」或「places」這樣的詞來避免使用「store」,這在本文中具有技術含義。


  1. eax是4B。 axeax的低2字節,就像alax的低字節。請參閱維基上的鏈接。我認爲維基百科的x86文章有一個顯示寄存器子集名稱的寄存器圖。 (rdi/edi/di/dilrdi/dil僅在64位模式),EFLAGS等提供)

  2. "string", 10, 0是具有換行和終止零字節的字符串。


push ebp     ; calling convention 
    mov ebp, esp 

製作堆棧幀是不是 「調用約定」 的一部分。 gcc現在默認爲,因爲現代的調試信息格式允許堆棧回溯調試和異常處理,即使沒有它。製作堆棧框架是ABI的一個可選部分,但不完全是你稱之爲「調用約定」的一部分。該術語的含義僅限於函數找到它們的參數,以及它們如何返回它們,除非我錯了。

+0

是必要的',10,0'部分,還是隻是爲了讓printf輸出看起來不錯? – Everythingsucks

+0

@Everythingsucks:如果你想要一個換行符,10是必要的。在Hello World程序中省略'\ n'並親自查看。當然,'0'是絕對必要的。 C字符串的結尾僅由零字節標記;沒有長度存儲在其他地方printf知道字符串結束的地方。 –

相關問題