IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    CPU Instruction Pointer

    eryar发表于 2016-04-10 15:56:00
    love 0

    CPU Instruction Pointer

    eryar@163.com

    1.Introduction

    CPU对存储器的读写通过总线Bus来完成,总线又分为地址总线(Address Bus)、数据总线(Data Bus)、控制总线(Control Bus)。地址总线AB决定了CPU的寻址能力,即可以访问的存储空间的大小。数据总线DB决定了CPU的一次操作中可以处理的数据的大小,16位CPU一次可以加载两个字节,32位CPU一次可以加载4个字节。当然CPU的主频越大,那么在相同的时间内,处理的次数会更多。

    2.16bit CPU 

    由于8086CPU有20位地址总线,所以寻址能力为1MB。但是8086所有的寄存器都是16位的,如果由寄存器直接处理地址,那么一个16位的寄存器可以访问的最大地址为64KB。如何通过16位的寄存器来访问这1MB的空间呢?8086CPU折腾出一个地址加法器,通过加法器来根据两个16位地址来合成一个20位的地址,即物理地址=段地址X16+偏移地址。对应到CPU中就是CS和IP这两个寄存器。

    8086CPU中的CS和IP的内容提供了CPU要执行指令的地址。在CPU中,程序员能够用指令读写的部件只有寄存器,程序员可以通过改变寄存器中的内容实现对CPU的控制。CPU从何处执行指令是由CS和IP中的内容决定的,程序员可以通过改变CS和IP中的内容来控制CPU执行目标指令。

    若想同时修改CS和IP的内容,可以用形如jmp 段地址:偏移地址的指令完成。如下图所示:

    wps_clip_image-10222

    3.32bit CPU

    因为80386的CPU寻址能力是4GB,所以它的寻址模式是平坦模式,不需要用段地址+偏移地址来折腾。所以32位CPU的EIP寄存器对应了16位CPU中的CS和IP两个寄存器。修改了EIP寄存器就可以改变CPU要执行的指令。如下面一段简单代码:

    #include <stdio.h> 

    int main(int argc, char* argv[]) 
    { 
        mark: printf(
    "hi\n"); 

        
    goto mark; 

        
    return 0; 
    }

    使用了goto,在Debug时可以在Visual Studio中看到CPU中相关寄存器中的信息如下图所示:

    wps_clip_image-22411

    由上图可知,goto对应的汇编命令就是一个修改EIP寄存器的jmp指令。



    eryar 2016-04-10 23:56 发表评论


沪ICP备19023445号-2号
友情链接