本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
学习教材:《汇编语言(第4版)》王爽著 此笔记是书中内容+自我总结,方便查阅和复习 请支持原著
@[toc]
一、标志寄存器结构及部分说明整理
这些数据称为程序状态字(PSW)
| 标志 | 描述 | 真值 |
| CF | 进位、借位标志 | 合法进位、借位值均可 |
| PF | 偶数个“1”标志 | 1代表偶数个“1”,0代表奇数个“1” |
| ZF | 零标志 | 1代表零值,0代表非零值 |
| SF | 负值标志 | 1代表负值,0代表非负值 |
| DF | 方向标志 | 1代表向高地址,0代表向低地址 |
| OF | 溢出标志 | 1代表溢出,0代表未溢出 |
检测点11.1
写出标志位的值
检测点11.2
写出标志位的值
二、进位加法和借位减法指令笔记
Ⅰ、进位加法adc
格式同add
adc相当于在add的基础上再把CF的值加到第一个寄存器上
使用adc可以实现多位加法,但要确保过程中不能影响CF的值,切忌移动ds:si的时候使用add
Ⅱ、借位减法sbb
格式同sub
sbb相当于在sub的基础上再使第一个寄存器减去CF的值
使用sbb可以实现多位减法
三、cmp比较指令笔记
格式同sub
cmp的操作相当于减法但是不保存结果,只是改变标志寄存器
Ⅰ、无符号数的比较结果判断
大于等于又被称为不小于
比较大小的实际操作是作差,通过结果可以知道大小关系
其中:在比较两个数时,CPU自动比较了有无符号两种情况,并且得出结论也被独立存储供操作者调用
| 无符号数大小关系 | 判断依据 |
|---|---|
| ax=bx | zf=1 |
| ax≠bx | zf=0 |
| ax<bx | cf=1 |
| ax>=bx | cf=0 |
| ax>bx | cf=zf=0 |
| ax<=bx | cf OR zf为真 |
Ⅱ、有符号数的比较结果判断
溢出导致了存在判断出错的可能
| 有符号数大小关系 | 判断依据 |
|---|---|
| ax=bx | zf=1 |
| ax≠bx | zf=0 |
| ax<bx | sf XOR of为真 |
| ax>=bx | sf=of=0 |
| ax>bx | sf=of=1 |
四、比较转移指令笔记
| 指令 | 含义 |
|---|---|
| je | 等于则转移 |
| jne | 不等于则转移 |
| jb | 小于则转移 |
| jnb | 不小于则转移 |
| ja | 大于则转移 |
| jna | 不大于则转移 |
实质是检测flag转移,注意比较转移前任何可能改变标志位的指令
五、DF标志和串传送指令笔记
串传送指令主要有:movsb、movsw,功能是将ds:si所指的内存单元内容送入es:di所指的内存单元,大小为byte和word
运行结束后di和si会改变1,改变方向就由DF决定:DF=0递增1,反之递减1
串传送指令搭配rep,即重复指令,可以实现多字复制,改变CX指定重复次数,如rep movsb
DF的值可以单独设定,使用cld或std置0和置1,即cld向高位地址(默认),std向低位地址
六、pushf和popf
功能是对标志寄存器入栈和出栈,能够写入或读取标志寄存器
检测点11.4
下面的程序执行后ax=?
mov ax,0
push ax ;push 0
popf ;flag=0
mov ax,0fff0h
add ax,10h ;ax=10000H
pushf ;push 0000 0000 1000 0101B
pop ax
and al,11000101B
and ah,00001000B ;不变
答案:ax=0000 0000 1000 0101B
- 对照文章开头的flag寄存器格式,没学的标志位是置0
- add计算后:ax=10000H,不溢出不借位、方向默认为0、奇数个“1”、非零非负,因此flag=0 0 0 0 0(OF) 0(DF) 0(IF) 0(TF) 1(SF) 0(ZF) 0 0(AF) 0 1(DF) 0 1(CF) B
后记
- CPU对有、无符号两种情况均记录了标志,按照操作者的想法获取标志值即可。无符号运算看CF,有符号数看OF
- cld和std为clean df和set df
- 切忌在比较转移前使用add、sub等改变标志位,使用inc或dec