I'm trying to see the disassembled binary of a simple C program in gdb.
C program :
int main(){
int i = 2;
if (i == 0){
printf("YES, it's 0!\n");
}else{
printf("NO");
}
return 0;
}
The disassembled instructions :
0x0000000100401080 <+0>: push rbp
0x0000000100401081 <+1>: mov rbp,rsp
0x0000000100401084 <+4>: sub rsp,0x30
0x0000000100401088 <+8>: call 0x1004010e0 <__main>
0x000000010040108d <+13>: mov DWORD PTR [rbp-0x4],0x2
0x0000000100401094 <+20>: cmp DWORD PTR [rbp-0x4],0x0
0x0000000100401098 <+24>: jne 0x1004010ab <main+43>
0x000000010040109a <+26>: lea rax,[rip+0x1f5f] # 0x100403000
0x00000001004010a1 <+33>: mov rcx,rax
0x00000001004010a4 <+36>: call 0x100401100 <puts>
0x00000001004010a9 <+41>: jmp 0x1004010ba <main+58>
0x00000001004010ab <+43>: lea rax,[rip+0x1f5b] # 0x10040300d
0x00000001004010b2 <+50>: mov rcx,rax
0x00000001004010b5 <+53>: call 0x1004010f0 <printf>
0x00000001004010ba <+58>: mov eax,0x0
0x00000001004010bf <+63>: add rsp,0x30
0x00000001004010c3 <+67>: pop rbp
0x00000001004010c4 <+68>: ret
0x00000001004010c5 <+69>: nop
And I suppose the instruction,
0x00000001004010a4 <+36>: call 0x100401100 <puts>
points to
printf("YES, it's 0!\n");
Now let us assume it is,
then my doubt is why <push> is called here , but <printf> is called at 0x00000001004010b5 <+53>: call 0x1004010f0 <printf> ?
It's an optimization.
Calling
printfwith a format string that has no format specifiers and a trailing newline is equivalent to callingputswith the same string with the trailing newline removed.Since
printfhas a lot of logic for handling format specifiers butputsjust writes the string given, the latter will be faster. So in the case of the first call toprintfthe compiler sees this equivalence and makes the appropriate substitution.