0

I have been trying to learn to write assembly code for the AMD64 processor. I have been looking at code generated by gcc. Eventually, I began seeing instructions such as

    call *(%rax)

What is the * doing in front of the operand? Something like this came up in the System V ABI document I'm reading, and the answer to the above will help me continue on. Here is an example of the syntax used in context, taken from the System V ABI document itself:

    // System V ABI suggested implementation of a
    // C switch statement with case labels 0, 1, and 2,
    // and a default label.

    // Jump to the default case if the control variable is
    // less than 0.
         cmpl     $0, %eax
         jl      .Ldefault

    // Jump to the default case if the control variable is
    // greater than 2.
         cmp $2, %eax
         jg .Ldefault

         movabs   $.Ltable, %r11
         jmpq     *(%r11,%eax,8)  /* Here is that syntax. */

         .section .lrodata,"aLM",@progbits,8
         .align 8
    .Ltable: .quad .Lcase0
             .quad .Ldefault
             .quad .Lcase2
             .quad .previous
    .Ldefault:
         // Code for default case
    .Lcase0:
         // Code for case 0
    .Lcase1:
         // Code for case 1
    .Lcase2:
         // Code for case 2
  • 1
    Looks like a pointer dereference operator. – mustaccio Jan 19 '17 at 02:48
  • When you assembled an instruction with it and one without and examined the machine code what did you find? – old_timer Jan 19 '17 at 03:27
  • 2
    Possible duplicate of [What does \* address(found in printf) mean in assembly?](http://stackoverflow.com/questions/2559849/what-does-addressfound-in-printf-mean-in-assembly) – David Hoelzer Jan 19 '17 at 10:29
  • I first encountered it when looking at compiler generated code, and couldn't reproduce what I was doing. I finally used fuz's answer and tried (in C) void (*array[3])(); array[0] = f; (*array[0])(); In the generated code, the function was loaded into %rdx and then called as "call *%rdx". Strangely, the same didn't work with a function pointer not in an array. – Unclechromedome Jan 20 '17 at 04:34

1 Answers1

5

In AT&T syntax, an indirect jump or function call has its operand prefixed with an asterisk * to distinguish it from a direct jump or function call. The purpose of this is to distinguish a call to a function from an indirect call to a function pointer stored in a variable:

call function
call *function_pointer
fuz
  • 88,405
  • 25
  • 200
  • 352