x86汇编中Modulo(取模)操作实现求助:使用idiv/div遇阻
x86汇编中用div/idiv实现取模运算
取模运算的结果本质就是除法操作后的余数,x86指令集中的div(无符号除法)和idiv(有符号除法)指令执行后,余数会存放在固定寄存器中,直接读取该寄存器的值就能得到取模结果。
无符号取模(用div指令)
div用于无符号整数除法,规则如下:
- 16位除法:被除数放在
DX:AX,除数为16位;执行后商存在AX,余数(取模结果)存在DX - 32位除法:被除数放在
EDX:EAX,除数为32位;执行后商存在EAX,余数存在EDX - 64位除法:被除数放在
RDX:RAX,除数为64位;执行后商存在RAX,余数存在RDX
注意:无符号除法前必须将高位寄存器(DX/EDX/RDX)清零,避免出现错误的被除数组合。
示例:计算10 mod 3(无符号)
section .data dividend dd 10 ; 无符号被除数 divisor dd 3 ; 无符号除数 section .text global _start _start: mov eax, [dividend] ; 将被除数加载到EAX xor edx, edx ; 清零EDX,组成EDX:EAX作为完整被除数 div dword [divisor] ; 执行无符号除法 ; 此时EDX寄存器中的值就是10 mod 3的结果(1)
有符号取模(用idiv指令)
idiv用于有符号整数除法,余数的符号会和被除数保持一致,规则和div类似,但需要先对高位寄存器进行符号扩展:
- 32位除法:用
cdq指令将EAX的符号位扩展到EDX,形成有符号的EDX:EAX被除数 - 64位除法:用
cqo指令将RAX的符号位扩展到RDX
示例:计算-10 mod 3(有符号)
section .data dividend dd -10 ; 有符号被除数 divisor dd 3 ; 有符号除数 section .text global _start _start: mov eax, [dividend] ; 将被除数加载到EAX cdq ; 符号扩展EAX到EDX,组成有符号被除数EDX:EAX idiv dword [divisor] ; 执行有符号除法 ; 此时EDX寄存器中的值就是-10 mod 3的结果(-1),符号与被除数一致
关键注意事项
- 若除数为0,或除法结果的商超出目标寄存器的存储范围(比如16位除法中商大于65535),会触发除法异常
- 有符号除法必须使用符号扩展指令,否则负数被除数会被当作无符号数处理,导致结果错误
内容的提问来源于stack exchange,提问作者bet bet
相关产品推荐
相关产品推荐

