What does an asterisk * before an address mean in x86-64 AT&T assembly?

It’s AT&T assembly syntax:

  • source comes before destination
  • mnemonic suffixes indicate the size of the operands (q for quad, etc.)
  • registers are prefixed with % and immediate values with $
  • effective addresses are in the form DISP(BASE, INDEX, SCALE) (DISP + BASE + INDEX * SCALE)
  • Indirect jump/call operands indicated with * (as opposed to direct).

So, you have a jmpq for jumping to the absolute address which is stored in %rax * 8 + 0x402680, and is a quad word long.


AT&T syntax needed a way to distinguish RIP = foo (jmp foo) from RIP = load from some symbol address (jmp *foo). Remember that movl $1, foo is a store to the absolute address foo.

With other addressing modes, there’s no ambiguity between what kind of jump / call you’re doing, anything other than a bare label must be indirect. (GAS will infer that and warn about an indirect jump without * if you do jmp %rax or jmp 24(%rax) or anything other than a bare symbol name.)

(In 64-bit mode you’d normally actually use jmp *foo(%rip) to load a global variable into RIP, not use a 32-bit absolute address like jmp *foo. But the possibility exists, and before x86-64 when AT&T syntax was designed, was the normal way to do things.)

Leave a Comment