8086芯片寄存器简介
- 通用寄存器:
- 数据寄存器:
- AX (Accumulator):累加寄存器
- BX (Base):基地址寄存器
- CX (Count):计数器寄存器
- DX (Data):数据寄存器
- 指针寄存器:
- SP (Stack Pointer):栈指针寄存器
- BP (Base Pointer):基指针寄存器
- 变址寄存器SI, DI:
- 段寄存器:
- CS (Code Segment):代码段寄存器
- DS (Data Segment):数据段寄存器
- SS (Stack Segment):栈段寄存器
- ES (Extra Segment):附加段寄存器
- 控制寄存器:
- IP (Instruction Pointer):指令指针寄存器
- FLAG:标志寄存器,又称程序状态字PSW
- 参考文献
8086 CPU 中寄存器总共为 14 个,且均为 16 位 。即 AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG(PSW),CS,DS,SS,ES 。这 14 个寄存器按照一定方式又分为了通用寄存器,控制寄存器和段寄存器。
通用寄存器:
在 8086 CPU 中,通用寄存器有 8 个,分别是 AX,BX,CX,DX,SP,BP,SI,DI ,这些个寄存器除了自身的专门用途外,还可以用来传送数据和暂存数据,所以才称它们为通用寄存器 。
数据寄存器:
AX (Accumulator):累加寄存器,也称之为累加器;
BX (Base):基地址寄存器;
CX (Count):计数器寄存器;
DX (Data):数据寄存器;
数据寄存器有 AX,BX,CX,DX 四个组成,由于在 8086 之前的 CPU 为 8 位 CPU,所以为了兼容以前的 8 位程序,在 8086 CPU 中,每一个数据寄存器都可以当做两个单独的寄存器来使用,由此,每一个 16 位寄存器就可以当做 2 个独立的 8 位寄存器来使用 。除了4 个数据寄存器以外,其他寄存器均不可以分为两个独立的 8 位寄存器 。
AX 寄存器可以分为两个独立的 8 位的 AH 和 AL 寄存器;
BX 寄存器可以分为两个独立的 8 位的 BH 和 BL 寄存器;
CX 寄存器可以分为两个独立的 8 位的 CH 和 CL 寄存器;
DX 寄存器可以分为两个独立的 8 位的 DH 和 DL 寄存器;
以AX为例,当把AX看作两个8为寄存器 AH 和 AL 使用时,AH 和 AL 它们是互不相关的,也就是AH和AL应该被看做两个完全独立的寄存器 X 和 Y 。如下图所示,表示 16 位 寄存器 AX 表示成两个 8 位寄存器,其中 AH 表示高位的 8 位寄存器,AL 表示低位的 8 位寄存器 。
AX (Accumulator):累加寄存器
AX 寄存器,作为累加器,特殊用途是在使用DIV和MUL指令时使用。
DIV在 8086 CPU 中是除法指令,使用时应注意:
- 除数,除数可以是 8 位或者是 16 位的,保存在一个寄存器或者内存单元中。
- 被除数,默认放在AX中(或者AX和DX中):如果除数是8位,那么被除数是16位,放在AX中;如果除数是16位,那么被除数是32位,在DX中存放高16位,AX中存放低16位。
- 商和余数,如果除数为8位,那么AL存放DIV操作的商,AH存放DIV操作的余数;如果除数为16位,那么AX存放DIV操作的商,DX存放DIV操作的余数。
div reg
div 内存单元MOV DX,100H ;设置 32 位被除数的高 16 位为 100H
MOV AX,300H ;设置 32 位被除数的低 16 位为 300H
MOV BX,200H ;设置 16 位除数为 200H
DIV BX ;执行计算
MUL在 8086 CPU 中是乘法指令,使用时应注意:
- 乘数,两个乘数要么都是8位,要么都是16位。如果是8位数的相乘,一个默认放在AL中,另一个放在内存字节单元或者其他寄存器中;如果是16位相乘,一个默认放在AX中,另一个放在内存字单元或者其他寄存器中。
- 乘积,8位数相乘结果默认保存在AX中,16位数相乘,默认运算结果有32位,高16位在DX中,低16位在AX中。
mul reg
mul 内存单元MOV AX,80H ;设置 16 位乘数为 80H
MOV BX,10H ;设置 16 位乘数为 10H
MOV DX,0H ;清空用来保存乘法结果的高 16 位
MUL BX ;执行计算
BX (Base):基地址寄存器
BX主要是用做内存寻址时候表示偏移地址,[…]表示一个内存单元,使用格式如下:
mov 寄存器名,内存单元地址mov ax, [bx] ;默认情况下段地址[bx]的段地址在ds中mov ax, ds:[bx]mov ax, cs:[bx] ;可以显式地指明段地址mov al, [bx]mov 内存单元地址,寄存器名mov [bx], axmov [bx], ah
此外,BX还可以和BP,SI,DI等组合使用,用[…]表示一个内存单元,[…]中只能是数字、BX、BP,SI,DI或它们的组合。
CX (Count):计数器寄存器
CX 作为计数寄存器,在使用loop指令循环时用来指定循环次数的寄存器。而 CPU 在每一次执行 loop指令的时候,都会做两件事:一件就是令 CX = CX – 1,即令 CX 计数器自动减去 1;还有一件就是判断 CX 中的值,如果 CX 中的值为 0 则会跳出循环,而继续执行循环下面的指令。
mov ax, 2mov cx, 11s: add ax, axloop s...
DX (Data):数据寄存器
DX 寄存器,作为数据寄存器器,特殊用途是在使用DIV和MUL指令时使用。详情见 AX (Accumulator):累加寄存器
指针寄存器:
SP (Stack Pointer):栈指针寄存器;
BP (Base Pointer):基指针寄存器;
SP (Stack Pointer):栈指针寄存器
SP 寄存器上必须和 SS 段寄存器一起使用,表示栈顶的偏移地址,8086CPU中,有两个寄存器:
- 段寄存器SS 存放栈顶的段地址
- 寄存器SP 存放栈顶的偏移地址
任意时刻,SS:SP 指向栈顶元素,用法如下:
mov ax, 1000hmov ss, axmov sp, 0020h ;初始化栈顶,将10000h~1001fh当做栈段mov ax, csmov ds, ax ;设置数据段的段地址mov ax, [0]add ax, [2]mov bx, [4]add bx, [6]push bxpush axpop bxpop ax ;入栈和出栈操作
入栈:push ax
- (1)SP=SP–2;
- (2)将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶。
出栈:pop ax
- (1)将SS:SP指向的内存单元中的内容送入ax处;
- (2)SP=SP+2,SS:SP此时指向新栈顶。
BP (Base Pointer):基指针寄存器
以 […] 的方式访问内存单元而且在 […] 中使用了寄存器 BP 的话,那么如果在指令中没有明确或者说是显示的给出段地址时,段地址则使用默认的 SS 寄存器中的值(BX,SI,DI 会默认使用 DS 段寄存器)
mov bp, 10hmov ax, [bp] ;默认的段地址是SS中的段地址mov ax, ss:[bp] ; 和mov ax, [bp]是等价的
变址寄存器SI, DI:
SI (Source Index):源变址寄存器;
DI (Destination Index):目的变址寄存器;
SI,DI 两个寄存器的功能和 BX 差不多,自然,SI 和 DI 中也是可以暂存一般性数据的,同时,通过使用 SI 和 DI 寄存器也是可以用来完成寻址操作的。SI和DI可以分别和BX,BP组合使用。
段寄存器:
CS (Code Segment):代码段寄存器;
DS (Data Segment):数据段寄存器;
SS (Stack Segment):栈段寄存器;
ES (Extra Segment):附加段寄存器;
CPU访问内存单元时要给出内存单元的地址。所有的内存单元构成的存储空间是一个一维的线性空间。每一个内存单元在这个空间中都有唯一的地址,这个唯一的地址称为物理地址。
- 8086有20位地址总线,可传送20位地址,寻址能力为1M。
- 8086内部为16位结构,它只能传送16位的地址,表现出的寻址能力却只有64K。
8086CPU采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。段地址×16+偏移地址=物理地址,段的起始地址肯定是16的倍数,并且由于偏移地址最多16位,所以段长度最大为64KB(0000H~FFFFH)。
CS (Code Segment):代码段寄存器
CS中保存代码段寄存器的段地址,通常和IP一起使用,利用CS:IP确定当前需要执行的指令的地址。代码段是我们自己定义的一段内存,只是我们自己编程时候的逻辑定义。
DS (Data Segment):数据段寄存器
DS是数据段寄存器,存放的是数据段的段地址,偏移地址通常由BX,SI,DI或者常数给出,DS:BX。数据段是我们自己定义的一段内存,只是我们自己编程时候的逻辑定义。
SS (Stack Segment):栈段寄存器
SS是栈段寄存器,存放的是栈段的段地址,偏移地址通常由SP,BP给出,SS:SP。栈段是我们自己定义的一段内存,只是我们自己编程时候的逻辑定义。
ES (Extra Segment):附加段寄存器
ES是用于定义一个段的段地址,使用和CS、DS、SS类似。
控制寄存器:
IP (Instruction Pointer):指令指针寄存器;
FLAG:标志寄存器,又称程序状态字PSW;
IP (Instruction Pointer):指令指针寄存器
IP通常是和CS一起使用,CS:IP表示将要读取的指令的内存地址,CS表示代码段地址,IP是表示偏移地址。CPU执行指令的示意图如下图所示:
- (1)从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;
- (2)IP = IP + 所读取指令的长度,从而指向下一条指令;
- (3)执行指令。 转到步骤 (1),重复这个过程。
FLAG:标志寄存器,又称程序状态字PSW
- flag 和其他寄存器不一样,其他寄存器是用来存放数据的,都是整个寄存器具有一个含义。
- 而flag寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息。
8086CPU的标志寄存器有16位,其中存储的信息通常被称为程序状态字(PSW)。一共包含9个标志位:
- CF进位标志,值为1进位,为0无进位(加减法有无进,错位)
- PF奇偶标志,代表数据的奇偶,1为偶,0为奇(低8位的1的数量)
- OF溢出标志,1代表溢出,0代表未溢出(溢出正+正=负,负+负=正)
- AF辅助进位标志,1有进位,0无进位(0位起,第三位到第四位有进位)
- ZF判0标志,1代表值为0,0代表不为0
- SF符号标志,1代表负值,0代表非负值
- TF跟踪标志,单步执行,常用于汇编程序debug
- DF方向标志,1代表减少,0代表增加
标志位 | 标志含义 | 值为1的标记 | 值为0的标记 |
---|---|---|---|
CF | 进位标志(Carry Flag) | CY(Carry进位) | NC(No Carry无进位) |
PF | 奇偶标志(Parity FLag) | PE(Parity Even偶) | PO(Parity Odd奇) |
AF | 辅助进位标志(Auxiliary Carry Flag) | AC(Auxiliary Carry进位) | NA(No Auxiliary Carry无进位) |
ZF | 零标志(Zero Flag) | ZR(Zero零) | NZ(Not Zero非零) |
SF | 符号标志(Sign Flag) | NG(Negative负) | PL(Positive非负) |
TF | 跟踪标志(Trap Flag) | ||
IF | 中断标志(Interrupt Flag) | EI(Enable Interrup允许) | DI(Disable Interrupt禁止) |
DF | 方向标志(Direction Flag) | DN(Down减少) | UP(UP增加) |
OF | 溢出标志(Overflow Flag) | OV(Overflow溢出) | NO(No Overflow未溢出) |
Debug中的标志位的结果显示如下图所示。
参考文献
- 《汇编语言》,王爽著
- 博客 https://www.cnblogs.com/tiger2soft/articles/5141263.html
- 博客 https://blog.csdn.net/thebestway/article/details/104752033/
— end —