标志寄存器
标志寄存器
1.0 程序状态字 psw
-
program state word
-
标志寄存器和其他寄存器不一样,不是用来存放数据
-
标志寄存器是按位起作用的也就是说它的每一位都有专门的含义,记录特定的信息
-

-
flag中1,3,5,12,13,14,15在8086CPU中没有使用,不具有任何意义
-
而2,4,6,7,8,9,10,11位都具有特殊意义
1.1 ZF标志 第6位 零标志位
-
它记录相关指令执行后 zero
- 结果为0 ZF = 1
- 不为0 ZF = 0
-
例如
-
mov ax, 1 sub ax, ax ;指令执行后 结果为零 ZF = 1 mov ax, 2 sub ax, 1 ;指令执行后 结果不为零 ZF = 0 ;ZF标记记录相关的计算指令的结果是否为零- 计算影响标志位的有 add,sub,mul,div,and,or,inc,dec他们都是运算指令
1.2 PF标志 第2位 奇偶标志位
- 计算结果,所有二进制中1的个数 Parity
- 为偶数 PF = 1 0000 1111B
- 为奇数 PF = 0 0000 0111B
1.3 SF标志 第7位 符号标志位
- 他记录指令执行后 signal
- 结果为负 SF = 1
- 结果为正 SF = 0
- 如何区分正负数 补码
1.4 CF标志 第0位 进制标志位
- 一般情况下,在进行无符号数运算时,它记录了运算结果的最高位想更高位的进位值,或借位值 carry
- cpu在运算时,并不会丢弃这个进位值,而是记录在特殊的寄存器的某一位上

1.5 OF标志 第11位 溢出标志位
- overflow
- 没有溢出 OF = 0 nv
- 溢出 OF = 1 ov
1.6 CF和OF的区别
- CF 是对无符号数的运算才会有意义
- OF是对有符号的数进行运算才有意义
1.7 adc指令
- adc 是带位进制的加法指令,也就是加上SF,它利用了CF进制位记录的值
- 格式: adc 操作对象1 操作对象2
- 功能:操作对象1=操作对象1+操作对象2+CF
- 比如:adc ax,bx 实现的功能就是
- ax = ax + bx + SF
- adc指令执行后,也可能产生进位值,所以会对CF位进行重新的赋值
1.8 编程题
-
计算1ef000H 加上 201000H
-
assume cs:code ;计算1ef000H 加上 201000H code segment start: mov ax, 001eH ;将第一个数字分开存储在 ax,bx mov bx, 0f000H add bx, 1000H ;用第一个数低位16位加上第二个数的低16位 进位存储在SF中 adc ax, 0020H ;这里 ax = ax + 0020H + CF ;将结果存储在ax ,bx中 ;将进位的1 加载高位上 相当于加法的进1 mov ax, 4c00H int 21H code ends end start -
由于这样的功能,我们可以对任意大的数据进行加法计算
1.9 sbb 指令
-
sbb是带借位的减法指令,他利用了CF位上记录的借位值
-
格式: sbb操作对象1 操作对象2
-
功能:操作对象1=操作对象1-操作对象2-CF
-
比如:sbb ax,bx 实现的功能就是
- ax = ax - bx - SF
-
由于这样的功能,我们可以对任意大的数据进行减法法计算
-
计算003E1000H 减去 00202000H 结果放在ax bx中
-
assume cs:code ;计算003E1000H 减去 00202000H code segment start: mov ax, 003EH ;将第一个数字分开存储在 ax,bx mov bx, 1000H sub bx, 2000H ;用第一个数低位16位减去第二个数的低16位 进位存储在SF中 sbb ax, 0020H ;这里 ax = ax - 0020H - CF ;将结果存储在ax ,bx中 mov ax, 4c00H int 21H code ends end start -
sbb和adc是基于同样思想设计的两个指令,思路上相似
2.0 cmp指令
- cmp 是比较指令,功能相当于减法,只是不保存结果
- cmp 指令执行后,将对标志寄存器产生影响
- 其他指令通过识别这些被影响的标志寄存器来得知比较的结果
- 格式:cmp 操作对象1 - 操作对象2
- 功能: 不保存计算结果,仅仅根据计算结果,改变标志寄存器的设置
- 比如 cmp ax, ax
- 相当于进行 ax- ax的运行 ,结果为0,但是不在ax中保存 仅仅影响标志位
- 指令执行后
- ZF = 1 结果是否为0 0=1
- PF = 1 二进制的1是否为偶数 偶数=1
- SF = 0 是否为负数 负数=1
- CF = 0 是否有进制 有 = 1
- OF = 0 是否有溢出 有 = 1
- cmp 的设计思想
- 通过减法运算,改变标志寄存器的值 来记录相关比较的结果
2.1 检测比较结果的条件转移指令
-

-

-
编程题
-
if((ah-bh) == 0){ ah = ah + ah }else{ ah = ah + bh } //用汇编代码实现 -
assume cs:code code segment start: mov ah, 1 mov bh, 2 cmp ah, bh je s add ah, bh jmp short ok s: add ah, ah ok: mov ax, 4c00H int 21H code ends end start -
编程 在一段内存中以字节为单位找出数字为8的个数,将个数存储到ax中
-
assume cs:code,ds:data data segment db 8,11,22,8,11,22,8,11 data ends code segment start: mov ax, data ;与数据段挂钩 mov ds, ax mov bx, 0 ;初始化偏移地址 mov ax, 0 ;初始化变量 mov cx, 8 ;初始化循环次数 s: cmp byte ptr [bx], 8 ;进行比较指令 通过je 判断是否为零 je ok jmp short next ok: inc ax ;为零 ax+1 next: inc bx ;不为零 内存地址+1 比较下一个地址的数据 loop s mov ax, 4c00H int 21H code ends end start
2.2 DF标志和串传送指令
- DF是第10位,方向标志位 direction
- 在串指令中,控制每次操作后si,di的增减
- DF = 0 每次操作si,di 递增
- DF = 1 每次操作si,di递减
- 串传送指令 movsb move string byte
- 功能:以字节为单位的传送
- 实现:es乘16+di = ds乘16+si
- 如果DF为0 每次操作si,di 递增
- 如果DF为1 每次操作si,di 递减
- 当然也是可以 传送一个字 movsw move string word
- 8086CPU提供两条指令对DF标志位进行设置
- cld 指令 将DF标志寄存器为设置为0
- std 指令 将DF标志寄存器为设置为1
2.3 rep指令 repare
- 一般和movsw ,movsb配合使用
- 格式 rep movsb
- rep 的作用是根据cx的值,重复后面movsb串传送指令
2.4 编程题
-
将data段中的字符串复制到后面的空间
-
assume cs:code,ds:data data segment db 'Welcome to masn!' db 16 dup (0) data ends code segment start: mov ax, data mov ds, ax ;DS:SI 指向data:0 mov es, ax ;ES:DI 指向data:16 mov si, 0 mov di, 16 mov cx, 16 ;rep 循环16次 cld ;将DF方向标志寄存器设置为0 rep movsb ;进行copy mov ax, 4c00H int 21H code ends end start
2.5 pushf 和 popf
-
pushf :将标志寄存器的值压入栈中
-
popf :从栈中弹出数据, 送入标志寄存器
-
assume cs:code code segment start: mov al, 1 cmp al, 1 pushf ;将标志寄存器的值进行压栈 add al, al popf ;弹出标志寄存器 mov ax, 4c00H int 21H code ends end start

浙公网安备 33010602011771号