【问题标题】:Is Visual Studio emitting erroneous assembly code?Visual Studio 是否发出错误的汇编代码?
【发布时间】:2014-05-14 20:58:18
【问题描述】:

用VS2010反汇编如下函数

int __stdcall modulo(int a, int b)
{
    return a % b;
}

给你:

push        ebp  
mov         ebp,esp  
mov         eax,dword ptr [ebp+8]  
cdq  
idiv        eax,dword ptr [ebp+0Ch]  
mov         eax,edx  
pop         ebp  
ret         8  

这很简单。

现在,尝试与内联汇编相同的汇编代码失败,error C2414: illegal number of operands 指向 idiv。

我读了Intel's manual,它说 idiv 只接受 1 个操作数:

将 AX、DX:AX 或 EDX:EAX(股息)中的(有符号)值除以 源操作数(除数)并将结果存储在 AX (AH:AL) 中, DX:AX 或 EDX:EAX 寄存器

果然,去掉多余的 eax 编译,函数返回正确的结果。

那么,这里发生了什么?为什么VS2010会发出错误代码? (顺便说一句,VS2012 发出完全相同的程序集)

【问题讨论】:

  • 您是生成汇编输出(由编译器)还是反汇编编译后的二进制文件?
  • 你用的是什么汇编程序?
  • @FredLarson 我假设他正在使用 VS 2010 (ml.exe) 附带的汇编程序。
  • 我正在使用 IDE 中的反汇编功能
  • @Yuval 查看stackoverflow.com/questions/1020498/… 并在编译时生成程序集。

标签: c++ visual-studio-2010 assembly x86


【解决方案1】:

不同之处很可能是反汇编程序的作者打算让人类而不是汇编程序读取其输出。既然是反汇编,就假设底层代码已经被汇编/编译过了,为什么还要担心它是否可以重新汇编呢?

这里有两种主要的可能性:

  • 作者没有意识到或不记得对于 idiv 是隐含的股息(在这种情况下,这可能被认为是一个错误)。
  • 他们认为在输出中明确说明有助于读者理解反汇编流程(在这种情况下,它是一个特性)。如果没有显式操作数,很容易忽略idiv 在扫描反汇编时既依赖又修改eax

【讨论】:

    猜你喜欢
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 2015-09-12
    相关资源
    最近更新 更多