SS、SP、BP寄存器


SS, SP, BP 三個寄存器


SS:存放棧的段地址;
SP:堆棧寄存器SP(stack pointer)存放棧的偏移地址;

BP: 基數指針寄存器BP(base pointer)是一個寄存器,它的用途有點特殊,是和堆棧指針SP聯合使用的,作為SP校准使用的,只有在尋找堆棧里的數據和使用個別的尋址方式時候才能用到
比如說,堆棧中壓入了很多數據或者地址,你肯定想通過SP來訪問這些數據或者地址,但SP是要指向棧頂的,是不能隨便亂改的,這時候你就需要使用BP,把SP的值傳遞給BP,通過BP來尋找堆棧里數據或者地址.一般除了保存數據外,可以作為指針寄存器用於存儲器尋址,此時它默認搭配的段寄存器是SS-堆棧段寄存器.BP是16位的,再擴充16位就是EBP,用於32位編程環境的.一般高級語言的參數傳遞等等,轉換為匯編后經常由BP/EBP來負責尋址\處理.

SP,BP一般與段寄存器SS 聯用,以確定堆棧寄存器中某一單元的地址,SP用以指示棧頂的偏移地址,而BP可 作為堆棧區中的一個基地址,用以確定在堆棧中的操作數地址。

(下面這個像Win32匯編中的)
bp為基址寄存器,一般在函數中用來保存進入函數時的sp的棧頂基址
每次子函數調用時,系統在開始時都會保存這個兩個指針並在函數結束時恢復sp和bp的值。像下面這樣:
在函數進入時:
push bp     // 保存bp指針
mov bp,sp  // 將sp指針傳給bp,此時bp指向sp的基地址。
                  // 這個時候,如果該函數有參數,則[bp + 2*4]則是該子函數的第一個參數,[bp+3*4]則是該子函數的 第二個參數,以此類推,有多少個參數則[bp+(n-1)*4]。
.....
.....
函數結束時:
mov sp,bp  // 將原sp指針傳回給sp
pop bp       // 恢復原bp的值。
ret              // 退出子函數


http://my.oschina.net/orion/blog/15879
下面是按調用約定__stdcall 調用函數test(int p1,int p2)的匯編代碼
;假設執行函數前堆棧指針ESP為NN
push   p2    ;參數2入棧, ESP -= 4h , ESP = NN - 4h
push   p1    ;參數1入棧, ESP -= 4h , ESP = NN - 8h
call test       ;壓入返回地址 ESP -= 4h, ESP = NN - 0Ch (注意CALL指令會把返回地址壓入堆棧)
;//進入函數內
{
push   ebp                                     ;保護先前EBP指針, EBP入棧, ESP-=4h, ESP = NN - 10h
mov    ebp, esp                             ;設置EBP指針指向棧頂 NN-10h
mov    eax, dword ptr  [ebp+0ch]  ;ebp+0ch為NN-4h,即參數2的位置 這里可以看到了BP的作用了
mov    ebx, dword ptr  [ebp+08h]  ;ebp+08h為NN-8h,即參數1的位置 這里可以看到了BP的作用了
ub    esp, 8                                  ;局部變量所占空間ESP-=8, ESP = NN-18h (棧底的地址大)

                                                      ;這里就是為局部變量申請空間.
...
add    esp, 8                                  ;釋放局部變量, ESP+=8, ESP = NN-10h

                                                      ;(假設在上面的指令中EBP沒變的話, 直接MOV ESP, EBP即可達到堆棧平衡,

                                                      ; 事實上也經常這么用)
pop    ebp                                      ;出棧,恢復EBP, ESP+=4, ESP = NN-0Ch
ret    8                                           ;ret返回,彈出返回地址,ESP+=4, ESP=NN-08h,

                                                     ; 后面加操作數8為平衡堆棧,ESP+=8,ESP=NN, 恢復進入函數前的堆棧

                                                     ; 為什么是8? 因為Test子函數有兩個參數, 8就是對應了兩個參數入棧時SP減少了8

}
原來ESP就是一直指向棧頂的指針,而EBP只是存取某時刻的棧頂指針,以方便對棧的操作,如獲取函數參數、局部變量等


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM