請問popl %esp這個語句有什麼用處?

Y86對popl的write back部分專門有以下語句處理:

R[%esp]←valE

R[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 eax

pusha

....

push eax保存的地方改成新的堆棧地址

popa

pop 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?

TAG:彙編語言 | 計算機科學 | CSAPP |