使用-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"};
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;
}
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比将零移动到寄存器更快?