2011-08-24 81 views
3

我正在學習高級彙編語言,並且一直在討論堆棧的概念。我想我很瞭解它,但實際上我有一些問題。從堆棧彈出而沒有推入

堆棧增長減少,ESP寄存器始終指向堆棧頂部。在低內存中的地址。如果有東西被推入堆棧,那麼ESP應該減少。

EBP被用作幀指針,至於我的理解,應該總是比ESP更多。

然而,與以下程序:

stdout.put(esp, nl); 
stdout.put(ebp, nl); 
push(ike); 
stdout.put(esp, nl); 
stdout.put(ebp, nl); 
push(ike); 
stdout.put(esp, nl); 
stdout.put(ebp, nl); 
pop(eax); 
pop(eax); 
pop(eax); 
pop(eax); 
stdout.put(esp, nl); 
stdout.put(ebp, nl); 

這似乎並不如此。縱觀輸出:

0018FF6C 0018FF70

0018FF68 0018FF70

0018FF64 0018FF70

0018FF74 0018FF70

EBP總是相同的,ESP是由4個字節遞減第一次推,然後再推4個字節。

在此之後我感到困惑。在我的第一次兩次爆發後,ESP應該回到它開始的地方。如果我沒有把任何東西推到堆棧上,我怎麼能再做兩次彈出?我在彈什麼?

進一步彈出並打印出EAX會顯示一些數字,然後顯示0,然後顯示更多數字。所以,我絕對會彈出一些東西......但是什麼?我的程序存儲器屬於哪個部分,爲什麼沒有受到影響?

爲什麼EBP不受影響?

另外,爲什麼ESP減少4個字節,而不是8?

如果有人能幫助我理解這一點,我將不勝感激。

回答

1

EBP不會被推/流指令修改,它是手動設置的,所以除非您自己更改,否則它將保持不變。

IKE的推動導致4字節的變化,所以顯然你在這裏是32位模式。

EAX(32位)的4次彈出將導致16字節(10小時)更改,就像他們一樣。

不知道這裏出現了什麼問題。似乎按照我的預期工作?

+0

我毫不懷疑它正在工作,因爲它的意思是,這只是我不明白它。我認爲,雖然EBP手動設置...,如果不這樣做,它有時也在內部使用?我會認爲ESP會一次減少一個字節,而不是一次32個字節? –

+0

我的主要問題是爲什麼我可以繼續彈出我沒有推動的堆棧。實質上,如果我從程序中刪除推送insctruioncs,爲什麼我可以在沒有推送的情況下彈出?我在彈什麼?我將堆棧彈出到EAX中,但我不確定從堆棧中取出的是什麼。 –

+0

關於EBP的進一步問題......我認爲它總是堆棧的一部分,在返回地址之前...... –

0

堆棧用來保存每個函數的棧幀(即局部變量),返回地址,舊ebp(特別是當前ebp所在的位置)和函數參數以外的東西。所以你彈出的是函數的堆棧框架。
如果你拆開一個程序,你會看到:

push param3   ; suppose func takes 3 parameters, they're 
push param2   ; pushed in reversed order (C-style) 
push param1 
call func   ; call pushes also the return address, i.e. the 
         ; address of the instrucion after the call 

... 

func: 
push ebp    ; this is done for preserving the caller's stack frame 
mov ebp, esp   ; now we set up the beginning of func's stack frame 
sub esp, smth.  ; and its width, enough to fit all func's variables 

此時堆棧將是這樣的:

 00000058: arg3 
     00000054: arg2 
     00000050: arg1 
     0000004c: return address 
ebp -> 00000048: caller's ebp 
     ...   ...    - 
     00000034: random stuff  | func's stack frame, random because they 
     00000030: random stuff  | are uninitialized 
esp -> 0000002c: random stuff  - 

最後,你推,並且在時間彈出只有4個字節,因爲這是你機器的字大小,這樣你可以保存整個寄存器。在一個鏡頭