王爽汇编学习(三)
标志寄存器
标志寄存器有以下三个作用:
用来存储相关指令的某些执行结果
用来为CPU执行相关指令提供行为依据
用来控制CPU的相关工作方式
标志寄存器是按位存储数据的,8086有16位,标志寄存器也有16个位子存储标志。
按索引不好记忆,一般给其起别名。
ZF 标志
ZF 标志代表着 Zero Flag,它记录相关指令执行后,其结果是否为0。如果为0,那么zf=1,否则zf=0。
PF 标志
PF 标志代表着 Parity Flag,它记录着相关指令执行后,其结果的所有bit位中1的个数是否为偶数,如果1的个数为偶数,pf=1,否则,pf=0。
SF 标志位
SF 标志位代表着 Sign Flag,它记录相关指令执行后,其结果是否为负数,如果是负数,sf = 1,否则 sf = 0。
CF 标志位
CF 标志位代表着 Carry Flag,它记录无符号数运算是否产生了进位或者借位。如果运算结果的最高位产生了一个进位或借位,那么 cf = 1, 否则 cf = 0。
OF 标志位
OF 标志位代表着 Overflow Flag,它记录着有符号数运算时,结果超出了机器所能表示的范围。发生溢出,of = 1,否则 of = 0。
DF 标志位
DF 标志位代表着 Direction Flag,在串处理指令中,控制每次操作后si、di的增减。
df = 0 每次操作 si、di 递增。
df = 1 每次操作 si、di递减。
1 | ;movsb 类似于 |
adc 指令
adc 是带进位加法指令,它利用了CF位上记录的进位值。
比如adc ax,bx 实现的功能是:(ax)=(ax)+(bx)+CF
1 | mov ax,2 |
sbb 指令
sbb 是带借位减法指令,它利用CF位上记录的借位值。
比如 sbb ax,bx 实现的功能是:(ax)=(ax)-(bx)-CF
和adc思路差不多。
cmp 指令
cmp 是比较指令,cmp相当于减法指令,只不过不保存结果。cmp的结果将对标志寄存器产生影响。
受影响的有:ZF、PF、SF、CF、OF。
比较分为无符号比较和有符号比较。
无符号比较:检测 ZF、CF
指令 | 含义 | 检测的标志位 |
---|---|---|
je | 等于则转移 | zf = 1 |
jne | 不等于则转移 | zf = 0 |
jb | 低于则转移 | cf= 1 |
jnb | 不低于则转移 | cf = 0 |
ja | 高于则转移 | cf = 0 且 zf = 0 |
jna | 不高于则转移 | cf = 1 或 zf = 1 |
有符号比较:检测 SF、OF、ZF
书上并没有说,但是原理相同,这些指令也不需要死记硬背,理解即可。
pushf 和popf
pushf :将标志寄存器的值压栈
popf:从栈中弹出数据,送入标志寄存器
内中断
- 除法错误
- 单步执行
- 执行 into 指令
- 执行 int 指令
CPU需要分清中断的来源,由此引出了中断类型码:
- 除法错误 :0
- 单步执行:1
- 执行 into 指令:4
- 执行 int 指令: int n,指令中n为给CPU提供的中断类型码
根据中断类型码找中断向量表,找到对应的中断程序所放的地址,然后去执行相应的中断程序。
- 取得中断类型码 N
- pushf
- TF = 0,IF = 0
- push CS
- push IP
- IP = N * 4,CS = N*4+2
中断程序要做到以下步骤:
- 保存用到的寄存器
- 处理中断
- 恢复用到的寄存器
- 用iret 指令返回
这些很好理解,中断程序要用的寄存器,要保存现场,执行完中断后要恢复现场,然后再用iret返回到正常的程序中。
iret 指令用汇编描述为:
1 | pop IP |
int 和 iret指令配合使用,和call与ret差不多一样。
端口
端口的读写指令只有两条:in 和out,in 代表从端口读取,out 代表往端口写入数据。
在 in 和 out 指令中,只能使用 ax 或 al 来存放从端口读取的数据或要发送到端口中的数据。
访问 8 位端口时用 al,16位端口用 ax。对256~65535 的端口进行读写时,端口号放在dx中:
1 | mov dx, 3f8h |
shl 和 shr 指令
shl 是逻辑左移指令:
- 将一个寄存器或内存单元中的数据向左移位
- 将最后移出的一位写入CF中
- 最低位补0
1 | mov al 01001000b |
如果移动的位数大于1时,必须将移动位数放在 cl 中。
shr 是逻辑右移指令:
- 将一个寄存器或内存单元中的数据向右移位
- 将最后移出的一位写入CF中
- 最高位补0
左移一位相当于 X*2 ,右移一位 X/2
外中断
外中断分为可屏蔽中断和不可屏蔽中断,与内中断的区别是内中断是CPU内部产生的,外中断是CPU外部产生的。
可屏蔽中断看 IF 标志位,如果 IF标志位为 0 ,表示不响应可屏蔽中断,为 1 代表CPU执行完当前指令后响应中断。
sti 指令设置 IF =1
cli 指令设置 IF =0
对于8086CPU,不可屏蔽中断的中断类型码固定为2。
几乎所有的由外设引发的外中断都是可屏蔽中断。