在学习汇编的时候,碰到一些汇编指令,总是忘记,索性写一篇博客来记录.

状态寄存器(标志寄存器)

PSW(Program Status Word)程序状态字(即标志)寄存器,是一个16位寄存器,由条件码标志(flag)和控制标志构成,
如下所示:image-20220308210251394

条件码:
①OF(Overflow Flag)溢出标志,溢出时为1,否则置0.标明一个溢出了的计算,如:结构和目标不匹配。
②SF(Sign Flag)符号标志,结果为负时置1,否则置0。
③ZF(Zero Flag)零标志,运算结果为0时置1,否则置0。
④CF(Carry Flag)进位标志,进位时置1,否则置0.注意:Carry标志中存放计算后最右的位。
⑤AF(Auxiliary carry Flag)辅助进位标志,记录运算时第3位(半个字节)产生的进位置。
有进位时1,否则置0。
⑥PF(Parity Flag)奇偶标志.结果操作数中1的个数为偶数时置1,否则置0。
控制标志位:
⑦DF(Direction Flag)方向标志,在串处理指令中控制信息的方向。
⑧IF(Interrupt Flag)中断标志。
⑨TF(Trap Flag)陷井标志。

指令

jz和jnz

jz = jump if zero (结果为0则设置ZF零标志为1,跳转)
Jnz=jump if not zero # 跳转条件:ZF = 0,即零标志位未被置位
eg: test eax,100b; # b后缀代表二进制
jnz 0Xxxxx(地址); # 如果eax=100b,test返回1(逻辑 与 的结果为1),ZF = 0,jnz将会跳转

test和cmp

test普遍用法之一是测试寄存器是否为空.
eg: test ecx ecx
jz #0Xxxx;
如果ecx = 0,将ZF零标志置为1 (ZF = 1),jz跳转.

cmp属于算术运算指令
功能:相当于减法指令(sub),对操作数之间运算比较,不保存结果(与sub区别在这).
eg: mov ax,8
mov bx,3
cmp ax,bx
执行后:ax=8,bx=3,ZF=0,PF=1,SF=0,CF=0,OF=0.
通过cmp指令执行后,相关标志位的值就可以看出比较的结果。

cmp ax,bx的逻辑含义是比较ax,bx中的值。如果执行后:

ZF=1则AX=BX

ZF=0则AX!=BX

SF=1则AX<BX

SF=0则AX>=BX

SF=0并ZF=0则AX>BX

SF=1或ZF=1则AX<=BX

CPU在执行cmp指令的时候,也包含两种含义:进行无符号运算和进行有符号数运算。

两个有符号数A和B相减,得到的是负数,那么可以肯定A<B

如果是无符号数,看例子.

eg: mov ax, a
cmp ax, b
无符号的: ja : a >b
je : a=b
jb a=b
jbe a<=b
有符号的:
jg a>b
je a=b
jl a=b
jle a<=b

结论:
test 逻辑与运算结果为零,就把ZF(零标志)置1;
cmp 算术减法运算结果为零,就把ZF(零标志)置1。

对于jz和jnz,查看代码和理解汇编代码时,直接判断test和cmp的运算结果决定是否跳转,至于ZF标记位是系统得知运算结果的标记位。

标志转移

直接标志转移

指令格式 机器码 测试条件 如…则转移
JC 72 C=1 有进位
JNC 73 C=0 无进位
JZ/JE 74 Z=1 零/
JNZ/JNE 75 Z=0 不为零/
JS 78 S=1 负号
JNS 79 S=0 正号
JO 70 O=1 有溢出
JNO 71 O=0 无溢出
JP/JPE 7A P=1 奇偶位为偶
JNP/IPO 7B P=0 奇偶位为奇

间接标志转移

先用cmp指令比较再用下面的判断(少了一个 JE 为等于):
指令格式 机器码 测试格式 如…则转移
JA/JNBE() 77 CZ=0 >/
JAE/JNB() 73 C=0 >=/
JB/JNAE() 72 C=1 </
JBE/JNA() 76 CZ=1 <=/
JG/JNLE() 7F (SO)Z=0 >/
JGE/JNL() 7D SO=0 >=/
JL/JNGE() 7C SO=1 </
JLE/JNG() 7E (SO)Z=1 <=/