【问题标题】:* in front of instruction operand, GNU assembly, AMD64* 在指令操作数之前,GNU 汇编,AMD64
【发布时间】:2017-01-19 02:40:44
【问题描述】:

我一直在努力学习为 AMD64 处理器编写汇编代码。我一直在看 gcc 生成的代码。最终,我开始看到诸如

之类的说明
    call *(%rax)

操作数前面的 * 是做什么的?在我正在阅读的 System V ABI 文档中出现了类似的情况,上面的答案将帮助我继续。以下是上下文中使用的语法示例,取自 System V ABI 文档本身:

    // 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

【问题讨论】:

  • 看起来像一个指针解引用运算符。
  • 当你用它组装一条指令和一个不带它的指令并检查机器代码时你发现了什么?
  • 我在查看编译器生成的代码时第一次遇到它,并且无法重现我在做什么。我终于使用了fuz的答案并尝试了(在C中) void (*array[3])();数组[0] = f; (*数组[0])();在生成的代码中,该函数被加载到 %rdx 中,然后被称为“call *%rdx”。奇怪的是,同样不适用于不在数组中的函数指针。

标签: assembly x86-64 gnu


【解决方案1】:

在 AT&T 语法中,间接跳转或函数调用的操作数以星号 * 为前缀,以区别于直接跳转或函数调用。这样做的目的是区分对函数的调用和对存储在变量中的函数指针的间接调用:

call function
call *function_pointer

【讨论】:

    猜你喜欢
    • 2011-06-15
    • 2011-08-06
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 2011-11-09
    • 2018-10-04
    • 2014-06-19
    相关资源
    最近更新 更多