2012-09-30 73 views
0

我有這個彙編代碼,我認爲它的作用是使用printf函數打印。我不是很熟悉C,但是我創建了一個主函數,我打印出printf("%d, %d", x, y),其中x和y都是零。裝入C,printf函數

我將C代碼轉換爲程序集,但我得到了完全不同的東西。有人能幫我理解下面的彙編代碼是什麼嗎?

  mov %edx,0x8(%esp) 
      mov %eax,0x4(%esp) 
      movl $0x80486a0,(%esp) 
      call 8048360 <[email protected]> 
+1

程序集根據彙編程序和體系結構不同而不同,可能是一個好主意,可以說你正在使用哪一個,以及C編譯器...... – Perkins

回答

3

作爲你的組件的非常直譯,

mov %edx,0x8(%esp) 

舉動在EDX到堆棧的值在偏移8(ESP + 8)

mov %eax,0x4(%esp) 

移動eax中的值到堆疊在偏移4(ESP + 4)

movl $0x80486a0,(%esp) 

舉動[32位值] 0x80486a0到所述堆疊中的偏移0

這是一個非常基本的方法,函數的參數將被放置在堆棧上 - RTL或C順序。最低偏移量處的值是第一個參數(在這種情況下,是字符串文字在內存中的地址),最高偏移量處的值是最後一個參數。

當你打的電話:

call 8048360 <[email protected]> 

你的程序會跳轉到指定的地址(你的反彙編已確定爲printf函數),讀取來自堆棧內的值,執行打印操作,並然後返回到您的代碼,在您撥打電話後的下一條指令恢復操作。

我要去猜測,你的源看起來是這樣的:

void main() 
{ 
    int x =0, y=0; 
    printf("%d, %d", x, y); 
} 

根據您的OS /編譯器,你可能會保證EAX和EDX將在啓動時的值爲0。或者你可能會錯過你的代碼片段中的初始化代碼。

+0

+1這樣一個很好的解釋。:) –

+0

謝謝你回答:D,但我有一個問題:什麼是「代碼片段的初始化代碼」。 – FranXh

4

從事物的外表,這使三個參數壓入堆棧 - 兩個整數從edxeax,再加上看起來像一個地址來 - 大概地址它挑來存儲字符串文字(即,格式字符串)。之後,它叫printf

所以,底線是它看起來像你在你的問題中提供的源代碼的一個非常簡單的實現。

1

mov %edx,0x8(%esp):正在將edx的值移到堆棧指針(帶有0x8偏移量)。
mov %eax,0x4(%esp):請參閱上文。
movl $0x80486a0,(%esp):正在將地址0x80486a0加載到堆棧指針中。
call 8048360 <[email protected]>:正在調用函數printf。

+0

謝謝你的回答,但我有一個問題。我仍然不明白這條線是如何在我的代碼中完成的:movl $ 0x80486a0,(%esp):將地址0x80486a0加載到堆棧指針中。 – FranXh

+0

這不是你的代碼,它是調用函數的標準方式。無論何時調用任何函數,這都是在彙編級別執行的方式。堆棧指針填充了函數的起始地址,以便系統知道下一個要執行的代碼行。當代碼加載地址爲0x80486a0的堆棧指針時,這意味着,駐留在內存中的地址0x80486a0處的代碼將在接下來執行。 –