visual-c++ - 编译代码中的冗余指令

标签 visual-c++ compiler-construction assembly x86

这个问题在这里已经有了答案:




9年前关闭。




Possible Duplicate:
What's the point of LEA EAX, [EAX]?



在一次反汇编练习中,我观察到以下代码:

测试.cpp:
#include <stdio.h>

int main(int argc, char * argv[]) {
    for (int i = 0; i < 10 ; ++i) {
        printf("%i\n", i);
    }
    int i = 0;
    while ( i < 10) {
        printf("%i\n", i);
        ++i;
    }
    return 0;
}

使用 vc++ 2008 编译并优化:
cl /Ox test.cpp

main函数拆解:
.text:00401000 var_4           = dword ptr -4 ; BTW, IDA fails to see that esi is pushed to save it, not to allocate space to local variable
.text:00401000
.text:00401000                 push    esi
.text:00401001                 xor     esi, esi
.text:00401003
.text:00401003 loc_401003:                             ; CODE XREF: sub_401000+15j
.text:00401003                 push    esi
.text:00401004                 push    offset byte_40A150
.text:00401009                 call    sub_401038      ; printf 
.text:0040100E                 inc     esi
.text:0040100F                 add     esp, 8
.text:00401012                 cmp     esi, 0Ah
.text:00401015                 jl      short loc_401003
.text:00401017                 xor     esi, esi
.text:00401019                 lea     esp, [esp+0]
.text:00401020
.text:00401020 loc_401020:                             ; CODE XREF: sub_401000+32j
.text:00401020                 push    esi
.text:00401021                 push    offset unk_40A154
.text:00401026                 call    sub_401038      ; printf 
.text:0040102B                 inc     esi
.text:0040102C                 add     esp, 8
.text:0040102F                 cmp     esi, 0Ah
.text:00401032                 jl      short loc_401020
.text:00401034                 xor     eax, eax
.text:00401036                 pop     esi
.text:00401037                 retn

现在,正如您从示例代码中看到的那样,我并不完全是专家,但是考虑到我编写了原始代码,我能够弄清楚这个程序集列表。唯一困扰我的是以下行:
.text:00401019                 lea     esp, [esp+0]

编译器为什么要这样做?它不会影响任何寄存器或标志,而且它似乎是一个冗余代码。我唯一能想到的是,编译器将 jmp 在第二个循环(loc_401020)中转到的代码对齐,这可能是原因吗?

最佳答案

是的,看起来它正在插入填充以对齐跳转目标。如果您使用 /Fa让编译器产生汇编输出,显示为 npad 7 ,明确表示它正在插入填充。从那里开始,由汇编程序挑选出它可以找到的最有效的指令序列来使用指定的空间,同时使用尽可能少的 CPU 时间。

关于visual-c++ - 编译代码中的冗余指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7987622/

相关文章:

parsing - 左递归和右递归是否产生相同的解析树?

assembly - 电路解码所需的最小输入位数

c++ - 在内联汇编代码中使用 C++ 命名空间

java - VC++ 与 Java 的结果不一致

c++ - 我可以使用 MS 工具将浮点错误转变为 C++ 异常吗?

c++ - 如何使用getc编写getLine函数

c - 如何在汇编中处理二维数组

c++ - 任何使用 visual studio 2008 环境的基本 C++ 网站/书籍?

c# - 在没有 Visual Studio 2010 的情况下,我可以在哪里下载 C# 4.0 的编译器?

scala - 纯函数式编译器如何用类型信息注释 AST?