c++ - 为什么编译器左移0?

标签 c++ assembly visual-c++

在我写完这个简单的程序后,当我在 Visual Studio 中进入反汇编模式时,我注意到了一些奇怪的事情:编译器添加了一条左移 0 位的指令。

为什么要这样做?

这是 C++ 代码:

#include <iostream>

using namespace std;

int main(int argc, char **argv) {


    if (argc != 3)
        return 0;

    if (strcmp(argv[1], "-r") == 0) {
        printf("test");
    }

    return 0;
}

这是汇编代码:

...
        return 0;
00131C94  xor         eax,eax  
00131C96  jmp         main+57h (0131CC7h)  

    if (strcmp(argv[1], "-r") == 0) {
00131C98  push        offset string "-r" (0138B30h)  
00131C9D  mov         eax,4  
00131CA2  shl         eax,0  <------------------------- HERE
00131CA5  mov         ecx,dword ptr [argv]  
00131CA8  mov         edx,dword ptr [ecx+eax]  
00131CAB  push        edx  
00131CAC  call        _strcmp (01313D9h)  
00131CB1  add         esp,8  
00131CB4  test        eax,eax  
00131CB6  jne         main+55h (0131CC5h)  
        printf("test");
00131CB8  push        offset string "test" (0138BD0h)  
00131CBD  call        _printf (01313E8h)  
00131CC2  add         esp,4  
...

最佳答案

请注意,这是在评估 argv[1] 时使用的。 .

一般来说,argv[N]需要由编译器翻译成*((char**) ((char*) argv + N * sizeof *argv)) : 每个指针是sizeof *argv下一个字节。当N在编译时不知道,乘法需要在那里,shl是这样做的正常方式。*

自从 N在编译时是已知的,但你没有启用优化,我猜这会编译成

00131C9D  mov         eax,1
00131CA2  shl         eax,2

显然,即使优化被禁用,Visual Studio 也能够将其简化为您所看到的,但如果没有优化,它仍然无法摆脱 shl完全。

* 在这种特殊情况下,shl即使 N 也不需要在编译时未知:[ecx+eax*4]可以通过一条指令访问。这将是另一个通常会执行的优化。

关于c++ - 为什么编译器左移0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42886333/

相关文章:

c++ - 类中数据成员的大小不匹配

c++ - 如何在 Visual C++ 2019 社区中使用 c++20 std::is_constant_evaluated?

C++/Qt类初始化

python - 通过Python进行程序集注入(inject)

c++ - 如何使用 ld 创建共享库?

assembly - 了解intel汇编中的%rip注册

assembly - 优化 ARM 的汇编

c++ - Invalidate() 调试断言失败消息(MFC、VC++)

c++ - 无论用户安装或使用什么布局,如何使 SendInput 使用固定(en-US)布局?

c++ - GLib-GObject-CRITICAL ...断言 'quark > 0' 失败