为什么编译器向左移0?

ore*_*nge 12 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;
}
Run Code Online (Sandbox Code Playgroud)

这是汇编代码:

...
        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  
...
Run Code Online (Sandbox Code Playgroud)

小智 12

请注意,这用于评估argv[1].

通常,argv[N]需要由编译器转换为*((char**) ((char*) argv + N * sizeof *argv)):每个指针sizeof *argv在下一个之后是字节.如果N在编译时不知道,则需要乘法,这shl是正常的方法.*

既然N在编译时已知,但你没有启用优化,我会猜到这会编译到

00131C9D  mov         eax,1
00131CA2  shl         eax,2
Run Code Online (Sandbox Code Playgroud)

显然,即使禁用了优化,Visual Studio也可以将其简化为您所看到的内容,但如果没有优化,它仍然无法shl完全摆脱.

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