寄存器
- 1、什么是寄存器
- 2、寄存器分类
- 3、windows X86寄存器命名规则
- 4、寄存器相关术语
- 5、寄存器分类
- 5.1、RAX(accumulator register)
- 5.2、RBX(Base register)
- 5.3、RDX(Data register)
- 5.4、RCX(counter register)
- 5.5、RSI(Source index)
- 5.6、RDI(Destination index)
- 5.7、RSP(stack pointer)
- 5.8、RBP(Base pointer)
- 5.9、RIP(instruction pointer)
- 6、普通寄存器
- 6.1、R8~R15
- 6.2、YMM0~15
- 7、特别说明
- 8、汇编指令
- 8.1、数据格式
- 8.2:操作数格式(寻址方式)
- 8.3:汇编指令
- 8.3.1:数据传送指令
- 8.3.2:压入和弹出栈数据
- 8.3.3:算术和逻辑操作
- 8.3.4:控制指令
本篇博客是:栈-寄存器和函数状态专题第一篇文章,主要解释计算机中寄存器相关知识技术,下面的分析,我们都是基于下面这张图。
![在这里插入图片描述](https://img-blog.csdnimg.cn/c5c480f6d09348d48642625044d60b15.png)
💙💙💙💙:重点
%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位寄存器为例介绍)
---------------------------------------------------------------🎄🎄下面介绍通用寄存器-------------------------------------
-
通用功能寄存器:主要有四种即 【AX,BX,CX,DX】
-
-
细节方面:AX,BX,CX,DX可以再往下划分
👩AX(Accumlator Register):累加寄存器,它主要用于输入/输出和大规模的指令运算
👩BX(Base Register):基址寄存器,用来存储基础访问地址。
👩CX(Count Register):计数寄存器,在迭代的操作中会循环计数。
👩DX(Data Register):数据寄存器,它用于输入/输出操作,它还与AX一起使用,用于涉及大数值的乘法和除法运算。 -
这四种寄存器可以分为上半部分和下半部分。
👨【AX寄存器可以分为两个独立的 8位 AH 和 AL寄存器】
👨【BX寄存器可以分为两个独立的 8位 BH 和 BL寄存器】
👨【CX寄存器可以分为两个独立的 8位 CH 和 CL寄存器】
👨【DX寄存器可以分为两个独立的 8位 DH 和 DL寄存器】
👩🦰 AX的地位(0-7)位构成了 AL 寄存器,高8位(8-15)位构成了AH寄存器。 -
在认识了寄存器之后,我们通过一个示例看一下数据的具体存储方式。
比如:数据 19, 它在16 位存储器中所存储的表示如下:
寄存器的存储方式先是存储 低位,如果低位满足不了就存储高位,如果低位能够满足,高位就用0补全,在其他低位也能满足的情况下,其余位也用0补全。
-------------------------------------------------------🎪🎪🎢索引寄存器---------------------------------------------------
🎈🎈下面介绍索引寄存器
- 索引寄存器主要包含段地址的偏移量,索引寄存器主要分为:
- BP (Base Pointer): 基础指针,它是栈寄存器上的偏移量,用来定位栈上的变量。
- SP (Stack Point): 栈指针,它是栈寄存器上的偏移量,用来定位栈顶。
- SI (Source Index):变址寄存器,用来拷贝源字符串。
- 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)
-
accumulator register, 累加寄存器,👩通常用于存储函数的返回值,它主要用于输入/输出和大规模的指令运算,AX 寄存器可以说是使用频率最高的寄存器。
-
也可以用于存储其他值,只是通过RAX存储函数返回值属于惯例。
-
上图我们可以看到这个寄存器分为8个字节(每个字节8位),RAX是64位寄存器的称呼。
🤶🎅🤶 但是这个寄存器是可以拆分的,例如我们操作EAX,就是在对RAX的低32位进行操作。
同样类推:
AX表示RAX的低16位
AH表示RAX低16位中的高8位
AL表示RAX低16位中的低8位
除了了 RIP之外,其余的寄存器都可以做类似的拆分。 -
举例
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,计数寄存器。一般用于循环计数。
- 也可以称为数据寄存器,能够暂存一般性数据,可以分为CH 和CL
- 它也有专门功能:即计数器功能,当汇编指令使用 循环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)
- stack Pointer 栈指针寄存器
- 正常情况下存放栈顶地址
- 如果用于其他事务,使用完成之后需要恢复原先的数据
5.8、RBP(Base pointer)
- base pointer 基址寄存器
- 正常情况用于访问栈底地址,与RBP功能类似
- 如果用于其他事务,使用完成之后需要恢复原先的数据
---------------------------------------🧶🧶🧶控制寄存器--------------------------------------------------------------
5.9、RIP(instruction pointer)
- instruction pointer 指令指针
- 只读且不可拆分,指向下一条需要执行指令的地址
6、普通寄存器
6.1、R8~R15
- R8,R9, R10…R15属于普通寄存器,一般是可以任意使用的,不指定特定用途,支持拆分
- 拆分规则与特殊功能寄存器有所不同。 32位拆分寄存器以 D作为后缀(DWORD),16位寄存器以 W作为后缀 (WORD),8位则以 B作为后缀 (BYTE)。
6.2、YMM0~15
YMM015专门用于存储浮点数(包括float和double)。单个寄存器可以存放多个浮点数。例如YMM#支持存放四个64位数值或者8个32位值。支持拆分成XMM015。
7、特别说明
- RSP, RBP最好只用作常规用途。
- 如果另作他用,使用完之后应该恢复原来的数据,因为这两个寄存器包含栈帧信息,这对程序非常重要。
- 一般的寄存器只能存放一个值,但是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:数据传送指令
------------------------💜💜 数据传送指令举例💜💜-----------------------
- move : 数据传递指令,目的操作数不能是立即数,数据不能从内存直接传送到内存(如一定需要,转化成2条指令,从内存取数据到寄存器,然后从寄存器到内存)
💛💛💛💛 move $4, 17(%rsp) : 把数据4 存储到 17(%rsp)所在内存的地址值里。 - 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,其他指令都会修改条件码寄存器。
除了算数和逻辑操作指令可以改变条件码寄存器,下面的指令也可以改变:
-----------------------------------------💔💔访问条件码💔💔----------------------------
条件码通常不会直接读取,常用的使用方法有三种。
- 更具条件码的某种组合,将一个字节设置为0或者1
- 根据条件码进行跳转
- 有条件地传送数据
-----------------------------------------💔💔跳转指令💔💔----------------------------
--------------------------------💔💔条件传送指令💔💔----------------------------
--------------------------------💔💔转移控制💔💔----------------------------