汇编进位与溢出标志位

以例题开始说明:写出如下程序段执行后进位标志位与溢出标志位的变化

.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword

.code
main proc
    mov ax, 7ff0h
    add al, 10h  ;CF=1, OF=0       皆以无符号数计算 ax=7f00h
    add ah, 1    ;CF=0, OF=1                       ax=8000
    add ax, 2    ;CF=0, OF=0                       ax=8002

    invoke ExitProcess,0
main endp
end main

标志寄存器保存的是当前指令执行后的运算状态
CF只针对无符号数(将寄存器中的操作数都看作是无符号数)
OF只针对有符号数(将寄存器中的操作数都看作是有符号数)
故CF标志位的变化仅将数值看作无符号数(所有位都是数值),OF看作有符号数(最高位为符号位)


第一条ADD指令执行后:
1.对CF标志位,计算时数据看作无符号数
al == f0h
则al + 10h == 100h 两个8位二进制相加后数变为9位二进制数有进位,故CF == 1
2.对OF标志位,计算时数据看作有符号数(计算机中有符号数用补码计算,可将减法转换为加法)
al == f0h 即11110000 最高为为符号位,1则为负数
al + 10h 即11110000 + 00010000转换为补码相加:10010000 + 00010000 = 10100000[补]
对计算结果10100000[补]再求一次补即为最终结果:11100000未溢出,故OF == 0
(易错提示:误将有符号数化为无符号数计算,11110000 + 00010000结果上溢,OF == 1出错)


第二条ADD指令执行后:
1.对CF(数据无符号):7Fh + 1 = 80h,无进位,故CF = 0
2.对OF(数据有符号):7Fh + 1(有符号8位二进制数最大数为7Fh,十进制为127,加1后,上溢,故OF == 1)


第三条ADD指令执行后:
1.对CF(数据无符号):8000h + 2 = 8002h,无进位,故CF = 0
2.对OF(数据有符号):8000h + 2(1000000000000000b + 0...010b, 有符号数运算结果:1111111111111110,无溢出,故OF == 0)


注:
1.有符号无符号指的是最高位是否是符号位,即是以补码的形式看待还是以原码的形式看待
2.在计算机内部,所有信息都是用二进制数串的形式表示的。整数通常都有正负之分,计算机中的整数分为无符号的和带符号的,无符号数没有原码、反码和补码一说,只有带符号数才存在不同的编码方式
3.注意哪些标志位为无符号数运算:ZF CF AC 有符号运算OF SF
4.硬件如何检测溢出(即溢出标志位的取值):计算结果的最高有效位产生的进位(CF)与结果的最高位进行异或操作,异或的结果存入溢出标志位
5.溢出与进位两个共同点都是"存不了",但其监测测的结果数据范围不同,即有符号数与无符号数的表示范围不同,8位有符号数:120 + 120 = 240,超过[-128,127],OF == 1;8位无符号数:120 + 120 = 240,未超过[0, 255], CF == 0

附上述程序VS2017调试结果:

MOV指令执行
第一次ADD指令执行
第二次ADD指令执行
第三次ADD指令执行

附标志位寄存器图解:

Flags
Eflag

你可能感兴趣的:(汇编进位与溢出标志位)