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指針傳回給sppop bp // 恢復原bp的值。ret // 退出子函數
http://my.oschina.net/orion/blog/15879下面是按調用約定__stdcall 調用函數test(int p1,int p2)的匯編代碼;假設執行函數前堆棧指針ESP為NNpush p2 ;參數2入棧, ESP -= 4h , ESP = NN - 4hpush p1 ;參數1入棧, ESP -= 4h , ESP = NN - 8hcall test ;壓入返回地址 ESP -= 4h, ESP = NN - 0Ch (注意CALL指令會把返回地址壓入堆棧);//進入函數內{push ebp ;保護先前EBP指針, EBP入棧, ESP-=4h, ESP = NN - 10hmov ebp, esp ;設置EBP指針指向棧頂 NN-10hmov 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-0Chret 8 ;ret返回,彈出返回地址,ESP+=4, ESP=NN-08h,
; 后面加操作數8為平衡堆棧,ESP+=8,ESP=NN, 恢復進入函數前的堆棧
; 為什么是8? 因為Test子函數有兩個參數, 8就是對應了兩個參數入棧時SP減少了8
}原來ESP就是一直指向棧頂的指針,而EBP只是存取某時刻的棧頂指針,以方便對棧的操作,如獲取函數參數、局部變量等
新聞熱點
疑難解答