段寄存器的种类和作用:
1、代码段寄存器CS,用于存放当前正在运行的程序代码所在段。
2、数据段寄存器DS,用于存放数据段。
3、堆栈段寄存器SS,存放堆栈段。
4、附加段寄存器ES,存放当前程序使用附加数据段。
汇编标志位:
OF标志:溢出标志位(有符号数)
flag的第11位是OF,溢出标记位;一般情况下,OF记录了有符号数运算的结果是否
发生了溢出;如果发生了溢出,则OF=1;如果没有,则OF=0。
CF和OF之间的区别:CF是针对于无符号数运算,OF位是针对于有符号数运算。
DF标志:方向标志位
flag的第10位是DF,方向标志位;仅仅用于串处理指令中,控制着地址的变化方 向。
DF=0;每次操作之后地址递增;即从低地址向高地址处理数据串。
DF=1,每次操作之后地址递减,即从高地址向低地址处理数据串。
由于flag寄存器中的DF位决定着串传送指令执行之后,SI、DI的改变方向;因此
8086CPU也提供了相应的指令来对于DF位进行设置:
CLD指令:将标志寄存器的DF位,置为0
STD指令:将标志寄存器的DF位,置为1
IF标志:中断允许标志位
flag的第9位是IF,IF置为0,禁止其他的可屏蔽中断;如果允许处理可屏蔽中断, 则将IF置为1。
——相关操作指令:
STI指令:将IF设置为1,允许可屏蔽中断。
CLI指令:将IF设置为0,禁止可屏蔽中断。
TF标志:跟踪标志位
flag的第8位是TF,跟踪标志位用于标识CPU是否允许单步中断,以进行程序调试。
TF=0时,8086CPU处于正常状态;TF=1时,8086CPU处于单步状态,每执行一条指 令就自动产生一次单步中断。
8086的debug功能依赖于8086CPU的单步调试功能。
SF位:符号标志位(有符号数)
Flag的第7位是SF,符号标志位。它记录着相关指令执行后其结果是否为负;如果结 果为负,则SF=1;如果结果非负,则SF=0。
在计算机里面,通常使用补码来表示有符号数据。计算机的一个数据既可以看作有符 号数,亦可以看作无符号数。譬如:
0000 0001B,可以看作为无符号数1,也可看做有符号数+1。
1000 0001B,可以看作为无符号数129,也可以看作有符号数-127。
ZF位:零标志位
flag寄存器的第6位是ZF,零标志位;它记录着相关指令执行之后,其结果是否为
零;如果结果为零,那么ZF=1,如果结果不为零,那么ZF=0。
AF位:调整标志位
flag的第4位是AF,调整标志位;反映加减运算时最低半字节有无进位或者借位。最 低半字节有进位或借位时,AF=1,否则AF=0。
这个标志位主要由处理器内部使用,用于十进制算术运算的调整指令,用户一般不必 关心。
例如:8位二进制数运算0011 1010+0111 1100 = 1011 0110,低四位有进位,所以此 时的AF=1。
PF位:奇偶标志位
flag寄存器的第2位是PF,奇偶标志位;它记录着相关指令执行之后,其结果的所有
bit位中1的个数是否为偶数;如果1的个数为偶数,则PF=1,如果1的个数为奇 数,则PF=0。
CF标志:进位标志位(无符号数)
flag的第0位是CF,进位标志位。一般情况下,在进行无符号数运算时,它记录了运
算结果的最高有效位向更高位的进位值,或者从最高位的借位值。8位数据,98h +
98h,产生进位,CF=1。这个进位值在8位数据中无法保存,但CPU并不会丢弃,可 以在标志位保存。
数据寄存器
AX 寄存器称为累加器,常用于存放算术、逻辑运算中的操作数或结果。另外,所有的I/O 指令都要使用累加器与外设接口传递数据。
BX 寄存器称为基址寄存器 <>,常用来存放访问内存时的地址。
CX 寄存器称为计数寄存器,在循环、串操作指令中用作计数器。
DX 寄存器称为数据寄存器 <>,在寄存器间接寻址中的I/O指令中存放I/O端口的地址。
常用指令详解:
* 传输指令:MOV DST, SRC 执行操作:(DST) ← (SRC)
注意:
1)DST、SRC 不能同时为段寄存器 MOV DS, ES ×
2)立即数不能直接送段寄存器 MOV DS, 2000H ×
3)不允许使用AX、CX、DX 存放 EA(EA是中断允许控制的开中断的标志,当EA=1时,表示允许程度中断!如果为零,表示禁止中断!)
4)DST不能是立即数和CS(代码寄存器)。CS和IP寄存器的修改只能使用JMP
XX:YY指令进行修改,不能用MOV指令修改。通常来说,CS都是由OS分配的,应用程序不能对其进行修改。
5)DST、SRC不能同时为存储器寻址。因为两者的位宽是否匹配不能确定。
6)DST、SRC的类型要匹配。
7)不影响标志位(对所有的数据传送指令而言)。
8)在汇编中,为什么CS和IP寄存器不能作为目的操作数?因为CS寄存器中存放的是源程序,IP寄存器中存放的是程序指针,如果这两个寄存器可以作为目的操作数,就意味着源程序和程序指针可以被任意改变,那么计算机将不知道是执行源程序还是修改后的程序,以及如何执行程序了。
* 堆栈操作指令 PUSH/POP
进栈指令:
PUSH SRC,执行操作:(SP) ← (SP) – 2 ;((SP+1), (SP)) ← (SRC)
出栈指令:
POP DST执行操作:(DST) ← ((SP+1);(SP))(SP) ← (SP) + 2
注意:
* 段地址存放在SS中,堆栈指针SP在任何时候都指向栈顶,进出栈后自动修改SP。
* 堆栈操作必须以字为单位
* 不影响标志位
* 不能用立即寻址方式 PUSH 1234H ×
* DST不能是CS (CS只能用JMP指令间接修改) POP CS ×
* 数据交换指令 XCHG。 交换指令:XCHG OPR1, OPR2;执行操作: (OPR1)<->(OPR2)
注意:
1)不影响标志位;
2)不允许使用段寄存器,两个操作数必须有一个在寄存器中。(内存之间不能相互传送数据,因为不知位宽是否匹配)
BX=6F30H,BP=0200H,SI=0046H,AX=2105H
SS=2F00H,(2F246H)=4154H
XCHG BX,[BP+SI] ; (BX) = 4154H
XCHG AL,BH ; (AL)= 41H
* LEA(Load Effective Address)LEA OPRD1,OPRD2 ;格式
OPRD1: 目的操作数,可为任意一个16位的通用寄存器
OPRD2:源操作数(变量名,标号,地址表达式)
加载有效地址。将源操作数的地址加载到目的寄存器中。
注意:不是实际地址
LEA指令用来计算第二个操作数(源操作数)的有效地址,并且将该地址保存到第一个操作数(目的操作数)中。
例子:若TABLE为数据段0032H单元的符号名,其中存放的内容为1234H,
LEA AX,TABLE
该指令的含义是获得内存单元的有效地址并赋值给AX,(AX) = 0032H。
注意:
1)LEA BX, 2728H 错
LEA AX,[1234H] ;作用是将源操作数[1234H]的偏移地址送到AX ;
等价于
MOV AX,1234H。
* MUL CX; 表示让CX 和 AX相乘,结果存入AX。需要进位的话CF置为1,高位结果存进DX
* ROL AX,CL:位循环不会丢弃位。从数的一端循环出去的位会出现在该数的另一端。出去的数放进CF;
比如 [AX] = 1234H;(即0001 0010 0011 0100)[CL] = 0004H;
ROL AX,CL 指令执行之后,AX里面的内容左移4位
移1位变为0010 0100 0110 1000 CF = 0;
移2位变为0100 1000 1101 0000 CF = 0;
移3位变为1001 0001 1010 0000 CF = 0;
移4位变为0010 0011 0100 0001 CF = 1;
* DEC AX :执行后AX = AX – 1;
小知识
* MOV AX,[BX]与MOV AX,BX有什么区别?
后者的意思是 将BX里的内容送到AX里去,这个应该没问题吧; 前者的意思是
将BX里的内容当作内存地址,然后将该地址所指的内存单元里的东西取出来送到AX里去,比如说BX=0x1000,那么指令执行完后,AX等不等于0x1000呢?
不等! 而是到内存单元里去取数送到AX里去,那么到底取哪个单元里的内容呢? 地址为0x1000单元里的内容将被取出来送AX
* 计算机负数的表示范围-128至127?
负数补码中,-1补码是1111 1111,……,-127补码是1000 0001,-128补码是1000 0000,
0的补码是0000 0000,……,127的补码是0111 11