链接:http://www.cnblogs.com/BoyXiao/archive/2010/11/20/1882716.html
博主写的很好,看完之后绝对可以明了的。自己也做一个笔记,算是精简版本的。
8086 CPU 中寄存器总共为 14 个,且均为 16 位 。
即 AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG,CS,DS,SS,ES 共 14 个。
而这 14 个寄存器按照一定方式又分为了通用寄存器,控制寄存器和段寄存器。
通用寄存器:
AX,BX,CX,DX 称作为数据寄存器:
AX (Accumulator):累加寄存器,也称之为累加器;
BX (Base):基地址寄存器;
CX (Count):计数器寄存器;
DX (Data):数据寄存器;
SP 和 BP 又称作为指针寄存器:
SP (Stack Pointer):堆栈指针寄存器;
BP (Base Pointer):基指针寄存器;
SI 和 DI 又称作为变址寄存器:
SI (Source Index):源变址寄存器;
DI (Destination Index):目的变址寄存器;
控制寄存器:
IP (Instruction Pointer):指令指针寄存器;
FLAG:标志寄存器;
段寄存器:
CS (Code Segment):代码段寄存器;
DS (Data Segment):数据段寄存器;
SS (Stack Segment):堆栈段寄存器;
ES (Extra Segment):附加段寄存器;
通用寄存器的使用方式比较简单。
所以主要记录段寄存器的组合使用方式:
CS 寄存器 和 IP 寄存器:
经过前面对段的介绍,相信各位朋友对段寄存器应该也有一定的了解了,
下面将要介绍的是一组非常非常重要的寄存器,即 CS:IP 。
CS:IP 两个寄存器指示了 CPU 当前将要读取的指令的地址,其中 CS 为代码段寄存器,而 IP 为指令指针寄存器 。
也就是说,当一个可执行文件加载到内存中以后,CS:IP 两个寄存器便指向了这个可执行文件的起始地址,
然后 CPU 就可以从这个起始地址开始往下读取指令,
当读取完指令后,CS:IP 将会自动的改变,基本上是改变 IP ,从而指向下一条要读取的指令,这样就可以执行这个可执行文件了 。
最后再对 CS:IP 总结一下:
记住,在任何时刻,SS:SP 都是指向栈顶元素 。
其实关于栈的使用还是比较简单的,但是要注意的是 8086 CPU 并不会保证我们对栈的操作会不会越界 。
所以我们在使用栈的时候需要特别注意栈的越界问题 。
当使用 PUSH 指令向栈中压入 1 个字节单元时,SP = SP - 1;即栈顶元素会发生变化;
而当使用 PUSH 指令向栈中压入 2 个字节的字单元时,SP = SP – 2 ;即栈顶元素也要发生变化;
当使用 POP 指令从栈中弹出 1 个字节单元时, SP = SP + 1;即栈顶元素会发生变化;
当使用 POP 指令从栈中弹出 2 个字节单元的字单元时, SP = SP + 2 ;即栈顶元素会发生变化;
DS 寄存器和 ES 寄存器:DS(Data Segment):很显然,DS 中存放的是数据段的段地址 。
但是这里不得不再点一下,那就是我们对段的支持是在 CPU 上体现的,而不是在内存中实现了段,
所以事实上我们使用的段其实是一个逻辑概念,即是我们自己定义的,
再说白了,我定义一个段,我说它是数据段那它就是数据段,我说它是代码段那么它就是代码段,
它们其实都是一块连续的内存而已,至于为什么要区分为数据段和代码段,
很明显,是用来给我们编程提供方便的,即我们在自己的思想上或者说是编码习惯上规定,
数据放数据段中,代码放代码段中 。而我们在使用数据段的时候,为了方便或者说是代码的编写方便起见,
我们一般把数据段的段地址放在 DS 寄存器中,当然,如果你硬要觉得 DS 不顺眼,那你可以换个 ES 也是一样的,
至于 ES(Extra Segment) 段寄存器的话,自然,是一个附加段寄存器,如果再说得过分点,
就当它是个扩展吧,当你发现,你几个段寄存器不够用的时候,你可以考虑使用 ES 段寄存器,
一个代码实例:
ASSUME CS:CODES CODES SEGMENT START: MOV AX,1000H MOV DS,AX MOV AL,1 MOV BX,0 MOV CX,5 ;设计一个循环,让其循环 5 次 s: MOV [BX],AL ;这里 [BX] 并没有指定段地址哦 INC AL INC BX LOOP s MOV AH,4CH INT 21H CODES ENDS END START
最后还提醒一点,那就是 8086 CPU 不支持直接将一个数据送入段寄存器中,
也就是下面的做法是错误的:
MOV DS,1000H
FLAG 寄存器中存储的信息通常又被称作程序状态字(PSW)
下面我给出一幅 FLAG 寄存器中各个位的示意图:
CF(Carry FLag) - 进位标志(第 0 位):
CF: 进位标志是用来反映计算时是否产生了由低位向高位的进位,或者产生了从高位到低位的借位 。
PF(Parity FLag) - 奇偶标志(第 2 位):
PF: 奇偶标志是用来记录相关指令执行后,其结果的所有的 Bit 位中 1 的个数是否为偶数 。
AF(Auxiliary Carry FLag) - 辅助进位标志(第 4 位):
AF: 用来辅助进位标志 。
ZF(Zero FLag) – 零标志(第 6 位):
ZF: 记录的是相关的指令执行完毕后,其执行的结果是否为 0 。
SF(Sign FLag) - 符号标志(第 7 位):
SF: 符号标志,其记录相关指令执行完以后,其结果是否为负数 。
TF(Trap FLag) - 追踪标志(第 8 位):
TF: 追踪标志,主要是用于调试时使用 。
IF(Interrupt-Enable FLag) - 中断允许标志(第 9 位):
IF: 中断允许标志,其决定 CPU 是否能够响应外部可屏蔽中断请求(以后会做详细介绍) 。
DF(Direction FLag) - 方向标志(第 10 位):
DF: 方向标志,其用于在串处理指令中,用来控制每次操作后 SI 和 DI 是自增还是自减 。
OF(OverFlow FLag) - 溢出标志(第 11 位):
OF: 溢出标志,其通常记录了有符号数运算的结果是否发生了溢出 。