C语言内联汇编实现32位整数相除及运算结果异常原因求解
错误原因拆解
- 第一,你把被除数和除数的位置完全搞反了。你要实现的是
val2 / val1,val2是被除数、val1是除数,但你现在的代码把val1放进了本该存被除数的eax寄存器,val2放进了完全不参与除法运算的ebx寄存器,运算逻辑从根上就不对。这也是你得到0结果的核心原因:如果误把val1当被除数、val2当除数,12除以234234的商就是0。 - 第二,你对
div/idiv指令的用法理解有误。x86 32位模式下,当除数为32位寄存器时,被除数默认是edx:eax拼接成的64位值:运算后商写入eax,余数写入edx。你直接写idiv eax,等于用edx:eax的值除以eax本身,和你要的val2/val1运算毫无关系。 - 第三,你尝试的
mov result abx本身是语法错误:x86没有名为abx的寄存器,你想写的应该是ebx,而ebx里存的是原始的val2值,直接赋值当然只会得到234234的固定结果。
修正后的实现
如果是无符号除法,直接用如下代码即可:
int func(int val1=12, int val2=234234) { int result; _asm { mov eax, val2 ; 被除数val2存入eax xor edx, edx ; 无符号除法前清空高位edx mov ebx, val1 ; 除数val1存入ebx div ebx ; 执行除法:edx:eax / ebx mov result, eax ; 取出商存入result } return result; }
如果是有符号除法,把xor edx, edx换成cdq指令(自动把eax的符号位扩展到edx),div换成idiv即可。
内容的提问来源于stack exchange,提问作者Elvin Jafarov
相关产品推荐
相关产品推荐

