2016-05-30 54 views
0

我想了解如何功能序言在彙編工作。我的書給出了下面的代碼:在內存方面的功能prolog

push %ebp 
    movl %ebp, %esp 

在按鍵的定義,它說,它通過減4 ESP的值,然後把操作數到由ESP指定的內存(字節?)。但是,這不會覆蓋圖中所示的一些數據嗎? enter image description here

另外我在這裏假設,每個段是4(字節?),但我很確定函數可以有超過4字節的分配堆棧空間?

接下來,第二條指令將ESP中的內容移動到EBP中,但是需要什麼?那已經在那裏了?並且當pop被調用時,它如何知道從堆棧中拿走多少? (所有的東西我解釋假設的事實說明movpush開始從他們指出,做任何操作的時候去了內存中)

+0

在AT&T程序集中,你的序言代碼看起來應該是這樣的:'pushl%ebp'' movl%esp,%ebp'。如果是錯字,請糾正。 –

回答

3

x86機器上的堆棧從較高地址向較低地址增長。
這是由push指令的語​​義體現:

push ebp

是語義上等同於

sub esp, 04h 
mov DWORD [esp], ebp 

技術上講,我們說堆棧充分的深淺因爲esp總是指向最後一個值推動爲明顯原因。

事實上堆棧指針以上的所有內容已被某些代碼推送,因此它被初始化並隱式分配內存。
另一方面,下面的所有內容都是可用內存。

從而一個push ebp不會覆蓋什麼有用的,一般沒有有史以來那樣做。

mov ebp, esp沒有采取什麼是EBP(那會是mov ebp, DWORD [esp],而是複製ESP的內容自己註冊到EBP
EBP用於兩個方面的原因:

  1. 它隱含地使用SS選擇器,而其他寄存器使用DS
  2. 在16位純代碼中,只有很少的寄存器可以用作基地址,因此(E)BP是專門爲此設計的。
    (E)BP指向的值ESP對隨機訪問堆棧和固定偏移量非常方便。

最後,pop指令是像push之一,其操作數確定操作的大小:push ax/eax/rax推棧上分別2,4和8個字節。
程序員仍然有負擔來保持堆棧平衡,如果需要甚至對齊,但通常沒有太多要問。


:86存儲器是字節尋址的,所以當一個寄存器間接製成,​​即,當我們訪問像mov eax, DWORD [ebx]寄存器指定的地址,該數字表示以字節爲單位的地址。
遞減由Ñ裝置讀Ñ字節下該號碼,所以從減去4 ESPESP新老地址之間的四個字節。

+0

當你說「esp」指向推入的最後一個值時;它指向最低的內存地址嗎? (所以如果你推0b0001然後讀esp [0]'你會得到1還是0? – Bula

+0

另外'move'和'push''處理'內容的寄存器而不是內存由寄存器的內容指定 – Bula

+0

@Bula * ESP *是堆棧指針,堆棧完全遞減,* ESP *保存最後一個值被推入的地址。如果您推入DWORD 1,然後按' mov eax,DWORD [esp]'then * EAX * is 1.In Intel syntax * indirect * and * direct * register addressing is using the use of []'。 –

0

布拉

多少字節與寄存器推消耗是取決於寄存器大小,這又是芯片架構的一個功能。在你的例子中,你正在使用32位寄存器,所以每個寄存器推送將消耗4個字節。

對於x86解釋這description可能是非常有用的。