MOVL多数据指令与装配优化对比

movl multi-data instruction and assembly optimization comparison

本文关键字:优化 多数据 指令 MOVL      更新时间:2023-10-16

考虑一个简单的循环:

for(int i=0;i<32;i++) 
    a[i] = i;

LLVM 拆装器显示以下程序集:

.LBB0_1:                                # =>This Inner Loop Header: Depth=1
movl    %eax, (%esp,%eax,4)
addl    $1, %eax
adcl    $0, %ecx
cmpl    $32, %eax
jne .LBB0_1
# BB#2:
xorl    %eax, %eax
addl    $140, %esp
ret

问题1:谁能解释movl %eax, (%esp,%eax,4)指令?

此外,Visual Studio拆装器输出以下程序集:

    ;for(int i=0;i<32;i++)
00F290B5  mov         dword ptr [ebp-94h],0  
00F290BF  jmp         main+60h (0F290D0h)  
00F290C1  mov         eax,dword ptr [ebp-94h]  
00F290C7  add         eax,1  
00F290CA  mov         dword ptr [ebp-94h],eax  
00F290D0  cmp         dword ptr [ebp-94h],20h  
00F290D7  jge         main+7Eh (0F290EEh)  
        ;a[i] = i;
00F290D9  mov         eax,dword ptr [ebp-94h]  
00F290DF  mov         ecx,dword ptr [ebp-94h]  
00F290E5  mov         dword ptr a[eax*4],ecx  
00F290EC  jmp         main+51h (0F290C1h)  
    ;return 0;
00F290EE  xor         eax,eax   

显然,LLVM的输出更加优化。

问题2:Visual Studio中是否有一个选项可以像LLVM那样优化代码?



更新:

将"解决方案配置"设置为"发布和优化"以"完全优化 (/Ox( "后的结果:

;   int a[32] = {0};
;   for(int i=0;i<32;i++)
 0039128B  xor         eax,eax  
 0039128D  lea         ecx,[a]  
 00391293  movd        xmm0,eax  
 00391297  pshufd      xmm0,xmm0,0  
 0039129C  paddd       xmm0,xmm1  
 003912A0  add         eax,4  
;   {
;       a[i] = i;
 003912A3  movdqu      xmmword ptr [ecx],xmm0  
 003912A7  lea         ecx,[ecx+10h]  
 003912AA  cmp         eax,20h  
 003912AD  jl          main+23h (0391293h)  
;   }
;   return 0;
; };
 003912AF  mov         ecx,dword ptr [ebp-4]  
 003912B2  xor         ecx,ebp  
 003912B4  xor         eax,eax  
 003912B6  call        __security_check_cookie (03916FDh)  
 003912BB  mov         esp,ebp  
 003912BD  pop         ebp  
 003912BE  ret  

movl %eax, (%esp,%eax,4)只是一个间接的内存存储。

它将%eax存储到内存位置:%esp + %eax * 4。在这种情况下:

  • %esp是数组a
  • %eax是索引i
  • 4int的大小。

对于第二个问题,Visual Studio 输出的代码看起来像是在没有优化的情况下完成的。内存负载和存储过多。

例如:dword ptr [ebp-94h]似乎是索引i变量。但是如果没有优化,它从未被提升为寄存器。

启用优化,您将看到它将生成更合理的代码。