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用於兩個方面的原因:
- 它隱含地使用SS選擇器,而其他寄存器使用DS。
- 在16位純代碼中,只有很少的寄存器可以用作基地址,因此(E)BP是專門爲此設計的。
有(E)BP指向的值ESP對隨機訪問堆棧和固定偏移量非常方便。
最後,pop
指令是像push
之一,其操作數確定操作的大小:push ax/eax/rax
推棧上分別2,4和8個字節。
程序員仍然有負擔來保持堆棧平衡,如果需要甚至對齊,但通常沒有太多要問。
注:86存儲器是字節尋址的,所以當一個寄存器間接製成,即,當我們訪問像mov eax, DWORD [ebx]
寄存器指定的地址,該數字表示以字節爲單位的地址。
遞減由Ñ裝置讀Ñ字節下該號碼,所以從減去4 ESP葉ESP新老地址之間的四個字節。
在AT&T程序集中,你的序言代碼看起來應該是這樣的:'pushl%ebp'' movl%esp,%ebp'。如果是錯字,請糾正。 –