汇编-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



浙公网安备 33010602011771号