聊一聊基础的CPU寄存器~

161 篇文章 12 订阅

寄存器:CPU内部的存储单元,用于存放从内存读取而来的数据(包括指令)和CPU运算的中间结果。

使用寄存器来临时存放数据而不直接操作内存原因如下:

  1. CPU的工作原理决定了有些操作只能在CPU内部进行。

  2. CPU读写寄存器的速度比读写内存的速度要快很多。

为便于交流和使用汇编语言编程,CPU厂商为每个寄存器都取了名字,如ADM64 CPU的rax、rbx、rcx等,这样就很方便的在汇编代码中直接使用寄存器的名称来进行编程,来看段Go编写的一行代码来直观的感受下寄存器的使用:

a := b + c

ADM64 Linux平台下用Go编译器编译上述代码可得如下AT&T格式的汇编代码:

mov   (%rsp),%rdx      //把变量b的值从内存中读取到寄存器rdxmov   0x8(%rsp),%rax   //把变量c的值从内存中读取到寄存器raxadd   %rdx,%rax        //把寄存器rdx和rax里面的值相加,之后将结果放回寄存器raxmov   %rax,0x10(%rsp)  //把寄存器rax中的值写回变量a所在的寄存器rsp

由上述汇编代码可以看到,一行Go代码被编译成了四行汇编指令,上述汇编代码里面的rsp、rap、rdp都是寄存器的名称(说明:AT&T格式的汇编代码中所有的寄存器名字前面都有一个%符号)。

可以看到,虽然只有四条指令,但也从侧面说明汇编代码比较简单,因为它所做的工作仅仅只是把数据在内存和寄存器中来回倒腾或是做一些基础的数学以及逻辑运算。

不同体系结构的CPU在其内部存在的寄存器的数量、类型以及名称可能会不同,本文只看ADM64 CPU这一种体系结构,这种CPU在其内部存在二十多个可直接被汇编语言中使用的调度器,还有几种仅在操作系统代码中才会出现,应用层的话,通常只会用到如下三个分类共19个调度器:

  1. 通用寄存器。共有rax、rbx、rcx、rdx、rsi、rdi、rbp、rsp、r8、r9、r10、r11、r12、r13、r14、r15这16个寄存器,CPU对它们的用途没有做特殊规定,可以自定义其用途(其中rsp、rbp这两个寄存器有特殊用途)。

  2. 程序计数寄存器(rip寄存器,也叫PC寄存器、IP寄存器)。用来存放下一条即将用来执行的指令的地址,它决定程序执行的流程。

  3. 段寄存器(fs、gs寄存器)。用来实现线程本地存储(TLS),比如ADM64 Linux下Go语言和pthread线程库都用fs存储器来实现线程的TLS(本地存储)。

上述存储器除了段寄存器是16位的,其它都是64位的,也就是八个字节,但是通用寄存器还可以当做32/16/8位存储器来使用。

不过使用的时候就需要换个名字了,比如可用eax来表示一个32位的寄存器,它使用的是rax寄存器的低32位。为方便各位查阅,下表为64位通用寄存器对应32/16/8位存储器的名称,如下:

64位32位16位8位
raxeaxaxal/ah
rbxebxbxbl/bh
rcxecxcxcl/ch
rdxedxdxdl/dh
rsiesisi-
rdiedidi-
rbpebpbp-
rspespsp-
r8~r15r8d~r15dr8w~r15wr8b~r15b

接下来看下rip、rsp、rbp这三个特殊的寄存器。

1、rip寄存器:存放CPU即将执行的下一条指令在内存中的地址。

来看段汇编语言:

0x0000000000400770: add   %rdx,%rax0x0000000000400773: mov   $0x0,%ecx

假设当前CPU正在执行第一条指令,我们可以看到,这条指令在内存中的地址就是0x0000000000400770,很明显,紧随其后的下一条将执行的指令在内存中的地址就是0x0000000000400773,此时,rip寄存器中所存储的值就是0x0000000000400773。

只需要记住,rip寄存器中存储的值不是CPU正在执行的指令在内存中的地址,而是紧随其后那一条将要被执行的指令在内存中的地址。

这里有人可能会问了,上述代码片段中并没有指令来让CPU去修改rip寄存器中的值呀,那rip寄存器是怎么实现上述功能的呢?

修改rip寄存器中的值这个操作是CPU自动控制的,不需要通过指令去修改,当然,CPU对外也提供了几条间接修改rip寄存器的指令,这个后面再详聊。

2、rsp栈顶寄存器以及rbp栈基寄存器。

上述两个寄存器都和函数调用栈相关,其中rsp寄存器一般用来存放函数调用栈的栈顶在内存中的地址,rbp寄存器通常用来存放函数的栈帧在内存中的起始地址。

编译器一般使用上述寄存器加一定偏移来访问函数局部变量或是函数参数,如下:

mov    0x8(%rsp),%rdx

上述汇编语言代码的指令把地址为0x8(%rsp)的内存中的值拷贝到寄存器rdx,此操作就是使用rsp寄存器加一定偏移来读取内存中的值。

到此基础的CPU寄存器相关内容聊得差不多了,这并不是需要了解的全部内容,后续文章中会有体现,喜欢本文的话,欢迎来个三连击。

扫码关注公众号,获取更多优质内容。

 

  • 1
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1.项目代码功能经验证ok,确保稳定可靠运行。欢迎下载使用! 2.主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时私信沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 【资源说明】 CPU寄存器组设计实验完整资料+项目说明.zipCPU寄存器组设计实验完整资料+项目说明(课程设计).zipCPU寄存器组设计实验完整资料+项目说明(课程设计).zipCPU寄存器组设计实验完整资料+项目说明(课程设计).zipCPU寄存器组设计实验完整资料+项目说明(课程设计).zipCPU寄存器组设计实验完整资料+项目说明(课程设计).zipCPU寄存器组设计实验完整资料+项目说明(课程设计).zipCPU寄存器组设计实验完整资料+项目说明(课程设计).zipCPU寄存器组设计实验完整资料+项目说明(课程设计).zipCPU寄存器组设计实验完整资料+项目说明(课程设计).zip CPU寄存器组设计实验完整资料+项目说明(课程设计).zip CPU寄存器组设计实验完整资料+项目说明(课程设计).zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luyaran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值