为何编译后的C函数反汇编显示双操作数idiv指令?
问题描述
我编写了如下C程序:
#include "stdio.h" __declspec(noinline) void DivideTest(int num, int denom) { int quo = num / denom; int rem = num % denom; printf("Quotient: %d\nRemainder: %d\n", quo, rem); } int main(int argc, char* argv[]) { // 使用volatile变量避免结果被硬编码 volatile int num = 20; volatile int denom = 3; DivideTest(num, denom); return 0; }
程序运行输出如下:
Quotient: 6 Remainder: 2
但在Release模式(开启优化)下编译后,通过Visual Studio调试查看反汇编,以及用dumpbin工具拆解,均显示DivideTest函数使用了双操作数idiv指令:
_DivideTest: push esi mov esi,edx mov eax,ecx cdq idiv eax,esi
然而所有资料均表明idiv仅支持单操作数,当我尝试编写双操作数idiv汇编代码时会编译失败,请问为何反汇编会显示双操作数idiv?
原因解析
这是Visual Studio反汇编器(以及dumpbin)采用的伪语法,目的是让指令含义更直观,并非实际存在双操作数的idiv指令。
标准x86架构中,idiv确实只有单操作数形式:idiv r/m32,它会将EDX:EAX中的64位被除数除以指定的32位操作数,商存储到EAX,余数存储到EDX。
Visual Studio的反汇编器把这个单操作数指令写成idiv eax, esi的形式,是为了显式写出隐含的被除数寄存器EAX,让读者一眼就能明确被除数和除数对应的寄存器——但这只是语法上的简化展示,实际机器码对应的仍是标准单操作数idiv esi。
你自己编写汇编代码时必须遵循标准x86指令集的语法,因此双操作数写法会编译失败,这和反汇编的展示语法并不冲突。
内容的提问来源于stack exchange,提问作者CuriousProgrammer
相关产品推荐
相关产品推荐

