C++:提高篇: 栈-寄存器和函数状态:windows X86-64寄存器介绍


本篇博客是:栈-寄存器和函数状态专题第一篇文章,主要解释计算机中寄存器相关知识技术,下面的分析,我们都是基于下面这张图。
在这里插入图片描述

💙💙💙💙:重点
%ebp 和 %esp:栈是从高地址向低地址延伸的。每个函数的每次调用,都有它自己独立的一个栈帧,%esp总是指向当前栈帧的顶部(低地址),而%ebp通常指向当前栈帧的底部(高地址),用于在栈帧中寻址

1、什么是寄存器

寄存器实际上知识存储数据的地方,只不过它集成在CPU里,访问寄存器的速度比访问内存更快,而内存的访问速度比硬盘更快。

2、寄存器分类

由于寄存器属于底层基础设施,贴近硬件,因此在不同体系结构和操作系统上,寄存器使用方式各异,但是基本上可以分为特殊功能寄存器和普通寄存器,特殊功能寄存器一般用于特定的功能,而普通寄存器可以随意使用。

3、windows X86寄存器命名规则

  • 前缀R:表示64位寄存器。例如:RAX
  • 前缀E:表示32位寄存器。例如:EAX
  • 后缀L:表示寄存器的低8位。
  • 后缀H:表示寄存器的9~16位

4、寄存器相关术语

  • byte:字节单位,表示8位二进制,是计算机的最小存储单元
  • WORD:字。一个字通常是指;两个字节(16位),针对windows X64平台,这个规则总是成立的,其他一些小众的平台不一定满足这一点。
  • DWORD:windows API的类型,用于表示“double world”的数据,即32位。
  • QWORD:windows API的类型,用于表示“qual word”的数据,即63位。
  • x86_x64:这是intel最先推出的指令集
  • 栈帧:用于记录程序在某时刻栈的状态,例如在调用一个函数之前,需要保存栈帧,用于在完成调用之后恢复现场。

5、寄存器分类

特殊功能寄存器分为:通用寄存器,索引寄存器。(我们以64位寄存器为例介绍)
---------------------------------------------------------------🎄🎄下面介绍通用寄存器-------------------------------------

  1. 通用功能寄存器:主要有四种即 【AX,BX,CX,DX】

  2. 在这里插入图片描述

  3. 细节方面:AX,BX,CX,DX可以再往下划分
    👩AX(Accumlator Register):累加寄存器,它主要用于输入/输出和大规模的指令运算
    👩BX(Base Register):基址寄存器,用来存储基础访问地址。
    👩CX(Count Register):计数寄存器,在迭代的操作中会循环计数。
    👩DX(Data Register):数据寄存器,它用于输入/输出操作,它还与AX一起使用,用于涉及大数值的乘法和除法运算。

  4. 这四种寄存器可以分为上半部分和下半部分。
    👨【AX寄存器可以分为两个独立的 8位 AH 和 AL寄存器】
    👨【BX寄存器可以分为两个独立的 8位 BH 和 BL寄存器】
    👨【CX寄存器可以分为两个独立的 8位 CH 和 CL寄存器】
    👨【DX寄存器可以分为两个独立的 8位 DH 和 DL寄存器】
    在这里插入图片描述
    在这里插入图片描述
    👩‍🦰 AX的地位(0-7)位构成了 AL 寄存器,高8位(8-15)位构成了AH寄存器。

  5. 在认识了寄存器之后,我们通过一个示例看一下数据的具体存储方式。
    比如:数据 19, 它在16 位存储器中所存储的表示如下:
    在这里插入图片描述
    寄存器的存储方式先是存储 低位,如果低位满足不了就存储高位,如果低位能够满足,高位就用0补全,在其他低位也能满足的情况下,其余位也用0补全。

-------------------------------------------------------🎪🎪🎢索引寄存器---------------------------------------------------
🎈🎈下面介绍索引寄存器

  1. 索引寄存器主要包含段地址的偏移量,索引寄存器主要分为:
  2. BP (Base Pointer): 基础指针,它是栈寄存器上的偏移量,用来定位栈上的变量。
  3. SP (Stack Point): 栈指针,它是栈寄存器上的偏移量,用来定位栈顶。
  4. SI (Source Index):变址寄存器,用来拷贝源字符串。
  5. DI(Destination Index): 目标变址寄存器,用来复制目标字符串。

------------------------------------------------🎭🎭🎭控制寄存器----------------------------------------------------------
🎀🎀下面介绍状态和控制寄存器
这两种寄存器是指令指针寄存器和 标志寄存器
IP (Instruction Pointer):指令指针寄存器,它是从Code Segment代码寄存器处的偏移来存储执行的下一条指令。
FLAG:FLAG寄存器用于存储当前进程的状态,这些状态有

  • 位置(Direction):用于数据块的传输方向,是向上传输还是向下传输
  • 中断标志位(Interrupt): 1–允许,0 --禁止
  • 陷入位(Trap) : 确定每条指令执行完成后,CPU是否应该停止。1–开启,0—关闭
  • 进位(Carry) :设置最后一个无符号算术是否带有进位
  • 溢出(Overflow): 设置最后一个由符号的运算是否溢出
  • 符号(Sign): 如果最后一次算术运算为负,则设置 1 —负, 0 —正
  • 零位(Zero) :如果最后一次算术运算结果为零, 1–零
  • 辅助进位(Aux Carry): 用于第三位到第四位的进位
  • 奇偶校验 (Parity):用于奇偶校验

5.1、RAX(accumulator register)

  1. accumulator register, 累加寄存器,👩通常用于存储函数的返回值,它主要用于输入/输出和大规模的指令运算,AX 寄存器可以说是使用频率最高的寄存器。

  2. 也可以用于存储其他值,只是通过RAX存储函数返回值属于惯例。
    在这里插入图片描述

  3. 上图我们可以看到这个寄存器分为8个字节(每个字节8位),RAX是64位寄存器的称呼。
    🤶🎅🤶 但是这个寄存器是可以拆分的,例如我们操作EAX,就是在对RAX的低32位进行操作
    同样类推:
    AX表示RAX的低16位
    AH表示RAX低16位中的高8位
    AL表示RAX低16位中的低8位
    除了了 RIP之外,其余的寄存器都可以做类似的拆分。

  4. 举例

mov ax,20  /* 将数字20存入寄存器 AX中*/
mov ah,80  /* 将数字80 存入寄存器 AX中的 AH(高位寄存器)中*/
mov al,10  /* 将数字10 存入寄存器 AX中的 AL(低位寄存器)中*/

5.2、RBX(Base register)

base register 基址寄存器,一般用于访问内存的基址
👩 :BX也被称为数据寄存器,即表明其能够暂存一般数据,同样也可以将BX当做两个独立的 8位寄存器使用即 BH 和BL
在这里插入图片描述
👨 BX除了具有暂存数据的功能之外,还用于寻址(即寻找物理地址),这就是为什么也有人将其称为基址寄存器,那么它存放的数据一般就用来作为偏移地址使用,因为偏移地址是相对于基址地址上的偏移。

5.3、RDX(Data register)

🧑:DX也是数据寄存器,能够暂存一般性数据。
在这里插入图片描述

5.4、RCX(counter register)

👧:counter register,计数寄存器。一般用于循环计数。

  1. 也可以称为数据寄存器,能够暂存一般性数据,可以分为CH 和CL
  2. 它也有专门功能:即计数器功能,当汇编指令使用 循环LOOP时,可以通过 CX来指定需要循环的次数,每次执行循环LOOP时间,CPU会做两件事
    一件事是:计数器自动减1
    另一件事是:判断CX中的值,如果CX中的值为0则跳出循环,继续执行循环下面的指令,如果CX中的值不为0,则会继续执行循环中所指定的指令。
    在这里插入图片描述

--------------------------------------索引寄存器--------------------------------------------------------------------

5.5、RSI(Source index)

source index : 源变址寄存器,字符串运算时常应用于源指针
在这里插入图片描述

5.6、RDI(Destination index)

destination index 目标变址寄存器,字符串运算时常用于目标指针。
在这里插入图片描述

5.7、RSP(stack pointer)

  1. stack Pointer 栈指针寄存器
  2. 正常情况下存放栈顶地址
  3. 如果用于其他事务,使用完成之后需要恢复原先的数据
    在这里插入图片描述

5.8、RBP(Base pointer)

  1. base pointer 基址寄存器
  2. 正常情况用于访问栈底地址,与RBP功能类似
  3. 如果用于其他事务,使用完成之后需要恢复原先的数据
    在这里插入图片描述

---------------------------------------🧶🧶🧶控制寄存器--------------------------------------------------------------

5.9、RIP(instruction pointer)

  1. instruction pointer 指令指针
  2. 只读且不可拆分,指向下一条需要执行指令的地址
    在这里插入图片描述

6、普通寄存器

6.1、R8~R15

  1. R8,R9, R10…R15属于普通寄存器,一般是可以任意使用的,不指定特定用途,支持拆分
  2. 拆分规则与特殊功能寄存器有所不同。 32位拆分寄存器以 D作为后缀(DWORD),16位寄存器以 W作为后缀 (WORD),8位则以 B作为后缀 (BYTE)。

在这里插入图片描述

6.2、YMM0~15

YMM015专门用于存储浮点数(包括float和double)。单个寄存器可以存放多个浮点数。例如YMM#支持存放四个64位数值或者8个32位值。支持拆分成XMM015。
在这里插入图片描述

7、特别说明

  1. RSP, RBP最好只用作常规用途。
  2. 如果另作他用,使用完之后应该恢复原来的数据,因为这两个寄存器包含栈帧信息,这对程序非常重要。
  3. 一般的寄存器只能存放一个值,但是XMM和YMM寄存器可以看作是数组,它们可以存放多个浮点数。

8、汇编指令

8.1、数据格式

intel数据类型汇编代码后缀
字节b
字(2字节)w
双字(4字节)l
四字(8字节)q
单精度(4字节)s
双精度(8字节)l

1: Intel使用 字(word)表示 16位数据类型
2:汇编指令除了要指明操作对象,还要指明操作对象的数据类型和长度,所以为指明操作对象的数据类型和长度,可以在指令后面加上表示数据类型的后缀,如:movl 和 movq 分别表示操作对象为双字和四字。
但是操作长度也可以通过寄存器给出,如:eax表示 32位,rax 表示64位

8.2:操作数格式(寻址方式)

在这里插入图片描述

8.3:汇编指令

8.3.1:数据传送指令

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
------------------------💜💜 数据传送指令举例💜💜-----------------------

  1. move : 数据传递指令,目的操作数不能是立即数,数据不能从内存直接传送到内存(如一定需要,转化成2条指令,从内存取数据到寄存器,然后从寄存器到内存)
    💛💛💛💛 move $4, 17(%rsp) : 把数据4 存储到 17(%rsp)所在内存的地址值里。
  2. lea:(load effective address)其实是mov的变形,它的源操作数看上去是一个内存引用,但并非从指定位置读入数据,而是将有效地址写入到目的操作数,目的操作时只能为寄存器。
    💚💚💚💚 lea17(%rsp), %rax :把17(%rsp)的内存地址的值写入到 %rax寄存器中。

8.3.2:压入和弹出栈数据

这两个操作都会修改 %rsp的值

8.3.3:算术和逻辑操作

注意,ADD S,D 由四条加法指令组成,即 addb, addw, addl 和 addq,其他指令也是如此
在这里插入图片描述
Intel把16字节的数称为八字(oct word)。下面是一些特殊的指令:
在这里插入图片描述

8.3.4:控制指令

-----------------------------------------💔💔条件码💔💔---------------------------------

CPU维护着一组单个位的条件码寄存器,它们描述了最近的算数或者逻辑操作的属性,可以检查这些寄存器来执行条件分支指令。最常用的条件码有:

  • CF:进位标志,最近的操作使最高位产生了进位,可用于检查无符号操作的溢出。

  • ZF:零标志,最近的操作得出的结果为0。

  • SF:符号标志,最近的操作得到的结果为负数 。

  • OF:溢出标志,最近的操作导致一个补码溢出(正溢出获负溢出)。

算术和逻辑操作列出的指令中,除了leaq,其他指令都会修改条件码寄存器。
除了算数和逻辑操作指令可以改变条件码寄存器,下面的指令也可以改变:
在这里插入图片描述

-----------------------------------------💔💔访问条件码💔💔----------------------------
条件码通常不会直接读取,常用的使用方法有三种。

  1. 更具条件码的某种组合,将一个字节设置为0或者1
  2. 根据条件码进行跳转
  3. 有条件地传送数据
    在这里插入图片描述
    -----------------------------------------💔💔跳转指令💔💔----------------------------
    在这里插入图片描述
    --------------------------------💔💔条件传送指令💔💔----------------------------
    在这里插入图片描述
    --------------------------------💔💔转移控制💔💔----------------------------
    在这里插入图片描述
  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值