为什么GCC使用xor清除寄存器?

时间:2017-09-29 03:42:35

标签: c gcc assembly x86

使用-O0和-O2使用GCC 6.4.1编译以下C程序,为main()函数提供以下结果。

public class Constant {

public static String [] name = {"Recovery Tools", "Admissions"};
public static String [] subNameRecoveryTools = {"Withdrawal Scales", "Shame Scale", "Drinking Limits", "Worksheets", "eBooks"};
public static String [] subNameAdmissions = {"Pre_Screen", "Intake Paperwork", "Client Handbook", "Meet your Therapist"};

-O0

int main(int argc, char *argv[]) {
  if (argc == 2) {
    printf("Checking License: %s\n", argv[1]);
    if (strcmp(argv[1], "AAAA-Z10N-42-OK") == 0) {
      printf("Access Granted!\n");
    } else {
      printf("WRONG!\n");
    }
  } else {
    printf("Usage: <key>\n");
  }
  return 0;
}

-O2

0x0000000000400586 <+0>:    push   rbp
0x0000000000400587 <+1>:    mov    rbp,rsp
0x000000000040058a <+4>:    sub    rsp,0x10
0x000000000040058e <+8>:    mov    DWORD PTR [rbp-0x4],edi
0x0000000000400591 <+11>:   mov    QWORD PTR [rbp-0x10],rsi
0x0000000000400595 <+15>:   cmp    DWORD PTR [rbp-0x4],0x2
0x0000000000400599 <+19>:   jne    0x4005ec <main+102>
0x000000000040059b <+21>:   mov    rax,QWORD PTR [rbp-0x10]
0x000000000040059f <+25>:   add    rax,0x8
0x00000000004005a3 <+29>:   mov    rax,QWORD PTR [rax]
0x00000000004005a6 <+32>:   mov    rsi,rax
0x00000000004005a9 <+35>:   mov    edi,0x400690
0x00000000004005ae <+40>:   mov    eax,0x0
0x00000000004005b3 <+45>:   call   0x400470 <printf@plt>
0x00000000004005b8 <+50>:   mov    rax,QWORD PTR [rbp-0x10]
0x00000000004005bc <+54>:   add    rax,0x8
0x00000000004005c0 <+58>:   mov    rax,QWORD PTR [rax]
0x00000000004005c3 <+61>:   mov    esi,0x4006a6
0x00000000004005c8 <+66>:   mov    rdi,rax
0x00000000004005cb <+69>:   call   0x400480 <strcmp@plt>
0x00000000004005d0 <+74>:   test   eax,eax
0x00000000004005d2 <+76>:   jne    0x4005e0 <main+90>
0x00000000004005d4 <+78>:   mov    edi,0x4006b6
0x00000000004005d9 <+83>:   call   0x400460 <puts@plt>
0x00000000004005de <+88>:   jmp    0x4005f6 <main+112>
0x00000000004005e0 <+90>:   mov    edi,0x4006c6
0x00000000004005e5 <+95>:   call   0x400460 <puts@plt>
0x00000000004005ea <+100>:  jmp    0x4005f6 <main+112>
0x00000000004005ec <+102>:  mov    edi,0x4006cd
0x00000000004005f1 <+107>:  call   0x400460 <puts@plt>
0x00000000004005f6 <+112>:  mov    eax,0x0
0x00000000004005fb <+117>:  leave  
0x00000000004005fc <+118>:  ret    

正如我在标题中所述,问题是为什么GCC清算eax

0x0000000000400490 <+0>:    cmp    edi,0x2
0x0000000000400493 <+3>:    push   rbx
0x0000000000400494 <+4>:    je     0x4004a4 <main+20>
0x0000000000400496 <+6>:    mov    edi,0x4006bd
0x000000000040049b <+11>:   call   0x400460 <puts@plt>
0x00000000004004a0 <+16>:   xor    eax,eax
0x00000000004004a2 <+18>:   pop    rbx
0x00000000004004a3 <+19>:   ret    
0x00000000004004a4 <+20>:   mov    rbx,rsi
0x00000000004004a7 <+23>:   mov    rsi,QWORD PTR [rsi+0x8]
0x00000000004004ab <+27>:   mov    edi,0x400680
0x00000000004004b0 <+32>:   xor    eax,eax
0x00000000004004b2 <+34>:   call   0x400470 <printf@plt>
0x00000000004004b7 <+39>:   mov    rdi,QWORD PTR [rbx+0x8]
0x00000000004004bb <+43>:   mov    esi,0x400696
0x00000000004004c0 <+48>:   call   0x400480 <strcmp@plt>
0x00000000004004c5 <+53>:   test   eax,eax
0x00000000004004c7 <+55>:   jne    0x4004d5 <main+69>
0x00000000004004c9 <+57>:   mov    edi,0x4006a6
0x00000000004004ce <+62>:   call   0x400460 <puts@plt>
0x00000000004004d3 <+67>:   jmp    0x4004a0 <main+16>
0x00000000004004d5 <+69>:   mov    edi,0x4006b6
0x00000000004004da <+74>:   call   0x400460 <puts@plt>
0x00000000004004df <+79>:   jmp    0x4004a0 <main+16>

而不是更明确的

xor eax,eax

在这种情况下。它在这里并不重要,因为每次执行程序最多只能达到一次,但让我们假设这发生在应用程序的关键部分。有没有理由让xoring比将零移动到寄存器更快?

0 个答案:

没有答案