請問popl %esp這個語句有什麼用處?
Y86對popl的write back部分專門有以下語句處理:
R[%esp]←valER[rA]←valM很好奇有什麼情況會出現popl %esp呢?
題主讀的是哪個版本的CS:APP?
popl %ebp 的意思就是在ebp-based stack frame上,ebp作為一個frame pointer,把caller棧幀的frame pointer恢復到ebp寄存器中。
放個傳送門:棧幀內返回地址是在local variables前還是在它們後面? - RednaxelaFX 的回答然而popl %esp …CS:APP里有用到這個么?
回公司找出書來,原來題主問的是這塊么一個pop esp的使用場景請看這個回答下面的評論區 @幽鬼 的評論。另外還有各種異想天開的地方都可以用,只要順手。例如:Uh Ah! I Happened To Use POP ESP ? Insanely Low-Level切換堆棧的時候可以用。比如中斷處理中,某個處理可能時間很久,這時候可以換個堆棧,然後開中斷。這個時候中斷重入就不會發生堆棧覆蓋。push eaxpusha....
push eax保存的地方改成新的堆棧地址
popapop esp;堆棧切換了。pusha,重新保存寄存器....
印象中在做context switching的時候有用。
Intel 手冊 上說:(4-386 Vol. 2B):
The POP ESP instruction increments the stack pointer (ESP) before data at the old top of stack is written into the
destination.
(POP ESP 相當於 ATT 語法的 popl %esp)。
所以除了它的操作對象是棧指針之外,和其他的 POP 操作並沒有太大的不同。我想了一下,好像正常的應用並沒有特別明顯的必須要這麼做的理由,能想到的一個好處是這樣可以少佔一個寄存器,畢竟 POP 不影響任何 flags。
此外想到的(不一定對)一個可能的原因是這樣做能夠給調試/跟蹤製造困難:假如設單步的話,下一個指令時,棧頂之上會被覆蓋,如果適當的設計(比如事先在棧頂之上寫某些特定的模式,然後在POP ESP之後檢查),則可以檢測到存在正在做在線跟蹤(即通過本機運行的調試器掛在進程上進行調試)的調試者,被跟蹤的程序可以據此作出一些破壞性的反應,從而提高程序的分析難度。這類「奇技淫巧」在上世紀八九十年代的病毒和加密軟體中比較常見。
當然,對使用模擬器或硬體調試器的「外科手術」式調試來說,這樣做就沒什麼意義了。%esp保存著棧指針,也就是棧頂元素的地址。
確實在CSAPP中沒看到popl %esp。推薦閱讀:
※《深入理解計算機系統》配套實驗:Bomblab
※彙編語言中call和ret指令必須成對出現嗎?
※關於CSAPP第12章並發編程的一個例子的疑惑?
※做CSAPP遇到點問題,希望能指點一番?
※如何取得32位無符號數二進位表示是否含有奇數個1?