zoukankan      html  css  js  c++  java
  • 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只是存取某时刻的栈顶指针,以方便对栈的操作,如获取函数参数、局部变量等

  • 相关阅读:
    Ubuntu12.04.1安装JDK 分类: ubuntu 20130506 11:45 1491人阅读 评论(0) 收藏
    Ubuntu 设置静态IP上网 分类: ubuntu 20130511 11:18 693人阅读 评论(0) 收藏
    linux 找回root用户密码 分类: ubuntu 20130426 15:57 199人阅读 评论(0) 收藏
    #小练习 类属性 分类: python 小练习 20130428 14:46 190人阅读 评论(0) 收藏
    VirtualBox虚拟机网络设置(四种方式) 分类: 测试 虚拟机 20130511 15:40 275人阅读 评论(0) 收藏
    异常处理 分类: python 20130502 11:13 172人阅读 评论(0) 收藏
    bash: ./java: cannot execute binary file 问题 分类: ubuntu 20130506 18:05 788人阅读 评论(0) 收藏
    在ubuntu上关闭tomcat的自启动 分类: ubuntu 20130507 09:45 302人阅读 评论(0) 收藏
    linux设置python环境变量 分类: python 20130513 10:37 1253人阅读 评论(0) 收藏
    #小练习 冒泡排序 分类: python 小练习 20130503 14:36 200人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/dongzhiquan/p/4960602.html
Copyright © 2011-2022 走看看