2

I have an extremely simple test binary that I'm looking at with objdump. I'm seeing an assembly instruction that confuses me. The code looks like this:

int main(int argc, char* argv[]){
    return 42;
}

When I do an objdump -d test, I see an interesting function:

00000000004004a0 <__do_global_dtors_aux>:
  4004a0:       80 3d 85 0b 20 00 00    cmpb   $0x0,0x200b85(%rip)       # 60102c <_edata>
  4004a7:       75 11                   jne    4004ba <__do_global_dtors_aux+0x1a>
  4004a9:       55                      push   %rbp
  4004aa:       48 89 e5                mov    %rsp,%rbp
  4004ad:       e8 7e ff ff ff          callq  400430 <deregister_tm_clones>
  4004b2:       5d                      pop    %rbp
  4004b3:       c6 05 72 0b 20 00 01    movb   $0x1,0x200b72(%rip)        # 60102c <_edata>
  4004ba:       f3 c3                   repz retq 
  4004bc:       0f 1f 40 00             nopl   0x0(%rax)

So 2nd from the bottom there, the instruction is f3 c3, or repz retq. Now looking up f3 in the x86 instruction set reference, I see this is a legacy prefix.

enter image description here

enter image description here

So c3 / ret is certainly not one of the listed valid instructions to precede it with it appears, so I'm wondering why my binary is doing this at all.

I'm executing gcc(4.8.5) like this:

gcc -g -Wall  -c src/test.c -o obj/test.o
gcc -g -Wall  obj/test.o -o bin/test
krb686
  • 1,726
  • 9
  • 26
  • 46
  • 1
    Very interesting, you're right, this is a duplicate. For anyone who is curious, in the linked blog of the top answer to the question linked by Michael above, *...this form is preferred to the simple ret either when it is the target of any kind of branch, conditional (jne/je/...) or unconditional (jmp/call/...), or when it directly follows a conditional branch.* As you can see from the 2nd instruction in this function, it is indeed the target of a conditional jump. – krb686 Aug 06 '17 at 23:55
  • 1
    `gcc -march=intel`, or any specific arch other than AMD K8/K8, will just use normal `ret` without padding, even when the `ret` is a branch target/fallthrough. E.g. use `gcc -O3 -march=native`. – Peter Cordes Aug 07 '17 at 00:09
  • Actually you're looking at code from the CRT start files linked into your executable, that run before/after `main()`. They're not recompiled every time, and were probably compiled with the default `-march=generic`, or written by hand in asm. – Peter Cordes Aug 07 '17 at 00:11

0 Answers0