汇编语言中的溢出(Overflow)与下溢(Underflow)
文章目录
- 汇编语言中的溢出(Overflow)与下溢(Underflow)演示
- 完整代码示例
- 关键概念总结表
- 重要说明
汇编语言中的溢出(Overflow)与下溢(Underflow)演示
以下是一个更全面的汇编代码示例,展示了不同类型和情况下的溢出与下溢现象,并附有详细注释。
完整代码示例
; 设置处理器模式和内存模型
.586 ; 使用586指令集
.model flat, stdcall ; 平坦内存模型,stdcall调用约定
option casemap:none ; 区分大小写; 引入库文件
includelib kernel32.lib ; Windows API库
includelib msvcrt.lib ; C运行时库ExitProcess PROTO, dwExitCode:DWORD ; 退出进程函数原型.data ; 数据段定义; 8位测试值ubyteMax db 0FFh ; 无符号8位最大值(255)ubyteMin db 00h ; 无符号8位最小值(0)sbyteMax db 7Fh ; 有符号8位最大值(+127)sbyteMin db 80h ; 有符号8位最小值(-128); 16位测试值uwordMax dw 0FFFFh ; 无符号16位最大值(65535)uwordMin dw 0000h ; 无符号16位最小值(0)swordMax dw 7FFFh ; 有符号16位最大值(+32767)swordMin dw 8000h ; 有符号16位最小值(-32768); 结果存储result8 db ?result16 dw ?flags db ? ; 存储标志位状态; 显示信息msgUnsignedOF db "无符号上溢发生(CF=1)",0msgSignedOF db "有符号上溢发生(OF=1)",0msgNoOverflow db "无溢出发生",0.code ; 代码段
main proc; ============================================; 1. 无符号8位数上溢(Unsigned 8-bit Overflow); ============================================mov al, ubyteMax ; AL = 255 (FFh)add al, 1 ; AL = 0, CF=1mov result8, alcall CheckUnsignedOverflow; ============================================; 2. 无符号8位数下溢(Unsigned 8-bit Underflow); ============================================mov al, ubyteMin ; AL = 0sub al, 1 ; AL = 255 (FFh), CF=1mov result8, alcall CheckUnsignedOverflow; ============================================; 3. 有符号8位数上溢(Signed 8-bit Overflow); ============================================mov al, sbyteMax ; AL = +127 (7Fh)add al, 1 ; AL = -128 (80h), OF=1mov result8, alcall CheckSignedOverflow; ============================================; 4. 有符号8位数下溢(Signed 8-bit Underflow); ============================================mov al, sbyteMin ; AL = -128 (80h)sub al, 1 ; AL = +127 (7Fh), OF=1mov result8, alcall CheckSignedOverflow; ============================================; 5. 无符号16位数上溢(Unsigned 16-bit Overflow); ============================================mov ax, uwordMax ; AX = 65535 (FFFFh)add ax, 1 ; AX = 0, CF=1mov result16, axcall CheckUnsignedOverflow; ============================================; 6. 有符号16位数上溢(Signed 16-bit Overflow); ============================================mov ax, swordMax ; AX = +32767 (7FFFh)add ax, 1 ; AX = -32768 (8000h), OF=1mov result16, axcall CheckSignedOverflow; ============================================; 7. 乘法溢出示例(Multiplication Overflow); ============================================; 有符号乘法溢出mov al, 64 ; AL = 64mov bl, 4 ; BL = 4imul bl ; AX = 256 (超过127), OF=1call CheckSignedOverflow; 无符号乘法溢出mov ax, 40000 ; AX = 40000mov bx, 2 ; BX = 2mul bx ; DX:AX = 80000 (超过65535), CF=1call CheckUnsignedOverflow; ============================================; 8. 移位操作溢出示例(Shift Operations); ============================================; 左移导致溢出mov al, 01000000b ; AL = 64shl al, 2 ; AL = 0 (CF=1, 因为最高位移出)call CheckUnsignedOverflow; 右移导致下溢mov al, 00000001b ; AL = 1shr al, 1 ; AL = 0 (CF=1)call CheckUnsignedOverflow; ============================================; 9. 无溢出情况(Non-overflow Cases); ============================================; 正常加法mov al, 100add al, 27 ; AL = 127 (无溢出)call CheckNoOverflow; 正常减法mov al, -50sub al, 50 ; AL = -100 (无溢出)call CheckNoOverflow; ============================================; 程序退出; ============================================invoke ExitProcess, 0 ; 退出程序,返回码0main endp; 检查无符号溢出子程序(CF标志)
CheckUnsignedOverflow procjc UnsignedOverflowDetectedret
UnsignedOverflowDetected:; 这里可以添加显示msgUnsignedOF的代码ret
CheckUnsignedOverflow endp; 检查有符号溢出子程序(OF标志)
CheckSignedOverflow procjo SignedOverflowDetectedret
SignedOverflowDetected:; 这里可以添加显示msgSignedOF的代码ret
CheckSignedOverflow endp; 检查无溢出情况子程序
CheckNoOverflow proc; 这里可以添加显示msgNoOverflow的代码ret
CheckNoOverflow endpend main
关键概念总结表
运算类型 | 示例 | 结果 | 关键标志位 | 检测方法 |
---|---|---|---|---|
无符号加法上溢 | 255 (FFh) + 1 | 0, CF=1 | CF | JC/JNC |
无符号减法下溢 | 0 - 1 | 255 (FFh), CF=1 | CF | JC/JNC |
有符号加法上溢 | +127 (7Fh) + 1 | -128 (80h), OF=1 | OF | JO/JNO |
有符号减法下溢 | -128 (80h) - 1 | +127 (7Fh), OF=1 | OF | JO/JNO |
无符号乘法溢出 | 40000 * 2 | 80000, CF=1 | CF | JC/JNC |
有符号乘法溢出 | 64 * 4 | 256, OF=1 | OF | JO/JNO |
左移溢出 | 01000000b << 2 | 00000000b, CF=1 | CF | JC/JNC |
右移下溢 | 00000001b >> 1 | 00000000b, CF=1 | CF | JC/JNC |
重要说明
-
标志位差异:
- 无符号数运算使用**进位标志(CF)**检测溢出
- 有符号数运算使用**溢出标志(OF)**检测溢出
-
数据宽度影响:
- 8位、16位、32位和64位数的溢出边界不同
- 示例中展示了8位和16位的情况
-
特殊运算:
- 乘法(IMUL/MUL)和移位(SHL/SHR)操作也会产生溢出
- 乘法结果可能需要更大的存储空间(如8位乘法的16位结果)
-
实际应用:
- 在关键计算后应检查相应标志位
- 可根据需要使用条件跳转(JC/JO)处理溢出情况
这个增强版的示例更全面地展示了各种溢出情况,包括不同数据宽度和运算类型,并提供了结构化的检测方法。