3

I'm in a gdb session to analyze a postmortem crash. I'm looking at disassemble output for a function and I see this:

=> 0x00007f8d354aed52 <+50>:    callq  *(%rax)

The => indicates that this was the instruction called at the time of the crash. So I got a seg fault calling the function at *(%rax). I'm pretty new to assembly. I see that parens around a register mean to deference (get the value at) that address. Thus (%rax) means to get the value of the pointer currently stored in %rax. What does the star decoration do on that? Does that further dereference that value (thus (%rax) is itself a pointer)? I'm having trouble googling *( assembly syntax.

This is x64 assembly generated from GCC 4.8 compiling C++ code.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
firebush
  • 5,180
  • 4
  • 34
  • 45
  • 2
    You’re right that there appears to be an extra level of indirection here, since (%rax) already indicates the memory at the address contained in rax. The asterisk is an idiosyncrasy of the gnu assembler syntax for indirect call instructions. It does not indicate an additional indirection. In Intel syntax, this would be “call [rax]”. – prl Jul 10 '19 at 23:40
  • 2
    Note you can switch gdb (and other gnu tools) to intel syntax mode. – Jester Jul 10 '19 at 23:47
  • Related: [Warning: indirect call without \`\*'](https://stackoverflow.com/a/67171563) describes what that means. Also, you can use Intel-syntax disassembly; `objdump -drwC -Mintel`, or GDB `set disassembly-flavor intel`, if you're not familiar with AT&T. Or asm GCC to generate Intel syntax in the first place with `gcc -S -masm=intel` ([How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116)) – Peter Cordes Apr 20 '21 at 02:25

1 Answers1

2

The asterisk indicates that the call is an indirect call. This is to distinguish call foo (call function foo) from call *foo (call function stored in variable foo). The instruction callq *(%rax) loads a quad word (64 bits) from the address stored in rax and calls the function beginning at that quad word.

Refer to the GNU assembler manual for details on the syntax.

fuz
  • 88,405
  • 25
  • 200
  • 352
  • It is the same instruction as `call *foo`, just with a different addressing mode: `(%rax)` base-register instead of `foo` 32-bit absolute or `foo(%rip)` RIP-relative. All of those use the same opcode ([indirect near `call r/m64`](https://www.felixcloutier.com/x86/call)), just a different ModRM byte. So does `call *%rax`, which uses a register instead of memory source for the 64-bit absolute target. – Peter Cordes Jul 11 '19 at 04:13