汇编实现(A % B) % (C % D):使用idiv无输出问题求助
实现有符号数取模运算(A % B) % (C % D)的解决方案
你当前的代码是执行连续乘法运算,要实现目标取模逻辑,需要正确使用idiv指令(有符号除法,余数符号与被除数一致),同时注意有符号数的符号扩展和运算步骤的拆分,以下是修改后的完整代码及关键说明:
INCLUDE Irvine32.inc INCLUDELIB Irvine32.lib INCLUDELIB kernel32.lib INCLUDELIB user32.lib .data A SBYTE 10d ; 8位有符号整数A B SBYTE 2d ; 8位有符号整数B(注意不能为0,否则触发除法错误) cc SBYTE 20d ; 8位有符号整数C D SBYTE 5d ; 8位有符号整数D(注意不能为0) result SBYTE ? ; 存储最终结果 msg BYTE "计算结果:",0 .code main PROC ; 第一步:计算 A % B mov al, A ; 把A加载到AL(8位) cbw ; 将AL的符号扩展到AX,形成16位有符号被除数(idiv 8位除数时,被除数是AX) idiv B ; AX / B,商在AL,余数在AH(即A%B的结果,符号与A一致) mov bl, AH ; 把A%B的余数暂存到BL ; 第二步:计算 C % D mov al, cc ; 把C加载到AL cbw ; 符号扩展到AX idiv D ; AX / D,余数在AH(即C%D的结果) mov cl, AH ; 把C%D的余数暂存到CL ; 第三步:计算 (A%B) % (C%D) mov al, bl ; 把第一个余数加载到AL cbw ; 符号扩展到AX idiv cl ; AX / CL,余数在AH(最终结果) mov result, AH ; 存储最终余数到result变量 ; 输出结果 mov edx, OFFSET msg call WriteString mov al, result cbw ; 扩展到AX以便用WriteInt输出 call WriteInt call Crlf call DumpRegs ; 可选:查看寄存器状态 exit main ENDP END main
关键注意事项:
cbw指令的作用:因为我们处理的是8位有符号数,idiv指令在除数为8位时,要求被除数是16位的有符号数(AX寄存器),cbw会自动将AL中的8位有符号数符号扩展到AH,确保除法运算的正确性。- 余数的存储:
idiv执行后,余数会存放在AH(除数8位时),商存放在AL,我们只需要余数部分。 - 除数非零检查:如果B、D的值为0,或者C%D的结果为0,会触发除法错误导致程序崩溃,实际使用时建议添加除数非零的判断逻辑。
- 输出逻辑:Irvine32库的
WriteInt需要16位(AX)或32位(EAX)的有符号数,所以需要用cbw将8位的余数扩展到AX再输出。
针对你测试数据的说明:
你当前的测试值中,C=20、D=5,计算C%D的结果是0,此时(A%B)=0,执行0%0会触发除法错误。建议调整测试数据,比如把D改为3,这样C%D=2,A%B=0,最终结果为0,程序可以正常运行。
内容的提问来源于stack exchange,提问作者Kapil Jadeja
相关产品推荐
相关产品推荐

