汇编-idiv有符号整数除法
有符号除法就是将一个有符号数除以另一个有符号数
有符号整数除法与无符号除法几乎相同,只有一个重要的区别:在进行除法之前,必须将被除数进行符号扩展。为了说明为何有此必要, 我们先不这么做。下面的代码使用MOV将 -101赋值给A X, 即DX:AX的低半部分:
.386 .model flat,stdcall option casemap:none .stack 4096 Include Irvine32.inc includelib Irvine32.lib ExitProcess PROTO,dwExitCode:DWORD .data .code main PROC mov bx,2 ;BX是16位除数 mov ax,-101 ;-101=FF9Bh mov dx,0 ;dx:ax是32位被除数 ;dx最高位是0,表示正数,dx:ax不是-101 ,而是0000FF9B=65435 idiv bx ;将DX:AX除以BX(有符号运算) quit: mov eax,[esi] INVOKE ExitProcess,0 main ENDP END main
因此, 必须在执行除法前, 使用CWD(字转换为双字) 指令将A X符号扩展到DX:AX中。下面是正确的代码:
.386 .model flat,stdcall option casemap:none .stack 4096 Include Irvine32.inc includelib Irvine32.lib ExitProcess PROTO,dwExitCode:DWORD .data .code main PROC mov bx,2 ;BX是16位除数 mov ax,-101 ;-101=FF9Bh mov dx,0 ;dx:ax是32位被除数 ;dx最高位是0,表示正数,dx:ax不是-101 ,而是0000FF9B=65435 ;因此, 必须在执行除法前, 使用CWD(字转换为双字) 指令将AX符号扩展到DX:AX中 cwd ;将AX符号扩展到DX:AX中 ;dx:ax=FFFF:FF9B=-101 idiv bx ;将DX:AX除以BX(有符号运算) ;ax=FFCEh=-50 dx=FFFF=-1 quit: mov eax,[esi] INVOKE ExitProcess,0 main ENDP END main
符号扩展指令(CBW、CWD和CDQ)
Intel提供了三个符号扩展指令:CBW、CWD和CDQ。
CBW(字节转换为字) 指令将AL的符号位扩展到AH
CWD(字转换为双字) 指令将A X的符号位扩展到DX
CDQ(双字转换为四字) 指令将EAX的符号位扩展到EDX
除法溢出
如果除法操作数产生的商无法装入目的操作数, 则会导致除法溢出(divide overflow) 。这将引起处理器异常并暂停当前程序。
.386 .model flat,stdcall option casemap:none .stack 4096 Include Irvine32.inc includelib Irvine32.lib ExitProcess PROTO,dwExitCode:DWORD .data .code main PROC mov ax,1000h mov bl,10h div bl ;AL装不下100h ;出现错误信息,如下图 quit: mov eax,[esi] INVOKE ExitProcess,0 main ENDP END main
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)