【问题标题】:Why can't I call Assembly functions from my C source using CodeBlocks?为什么我不能使用 CodeBlocks 从我的 C 源代码中调用汇编函数?
【发布时间】:2014-07-24 11:08:21
【问题描述】:

我正在尝试调用一个简单的程序集(作为稍后更复杂的测试),但是当我尝试运行程序时它崩溃了(该程序已停止响应)。

ma​​in.c:

#include <stdio.h>
#include <stdlib.h>

extern int bar(int param);

int main()
{
    int i=8;

    i = bar(i);

    printf("Hello world! - %i\n",i);
    return 0;
}

bar.S

.file "bar.S"
.text

.align 8
.global bar
bar:
    add %rdi,1000;
    mov %rax,%rdi;
    ret;

我担心这可能与我的编译器的配置方式有关(我更习惯于手持 Visual Studio,而不是处理真实环境)。

【问题讨论】:

标签: c assembly mingw codeblocks


【解决方案1】:

您正在使用 at&t 语法汇编,但您显然不熟悉它。简单的解决方案是将.intel_syntax noprefix 粘贴到bar.S 中,这样您就可以使用intel 语法了。

At&t 语法使用相反的操作数顺序和不同的有效地址格式等。您遇到了崩溃,因为add %rdi, 1000 在英特尔语法中表示add [1000], rdi,即将rdi 的内容添加到超出范围的内存位置1000。大概你想做add $1000, %rdi。要返回值,您还需要交换 mov %rax, %rdi 的操作数。

【讨论】:

    【解决方案2】:

    此代码不正确:

    add %rdi,1000;
    mov %rax,%rdi;
    

    请记住,在 AT&T 语法中,操作数的顺序是 source, destination。此外,立即值应以$ 为前缀。所以代码应该是:

    add $1000,rdi
    mov %rdi,%rax
    

    我删除了分号,因为它们不是必需的。

    此外,由于您似乎正在为 Windows 进行编译,因此您应该关注 Microsoft's 64-bit calling convention,而不是 System V。所以参数将在rcx,而不是rdi

    【讨论】:

      【解决方案3】:

      从这里开始

      int bar ( int param )
      {
          return(param);
      }
      

      单独编译并与main链接,看看main在做什么并通过,注意main使用edi而不是rdi。

      现在反汇编上面的函数。

      0000000000000000 <bar>:
         0:   89 f8                   mov    %edi,%eax
         2:   c3                      retq   
      

      edi 和 eax 也是如此。另请注意,这是 ATT 语法而不是 intel,因此它是向后的,目的地在右侧而不是左侧。

      所以我们自己做不同的口味:

      .global bark
      bark:
          mov %edi,%eax
          addl $1000,%eax
          retq
      
      .global barf
      barf:
          addl $1000,%edi
          mov %edi,%eax
          retq
      
      
      .global bar
      bar:
          add $1000,%edi
          mov %edi,%eax
          retq
      

      用 main 而不是 C 版本组装和链接。和

      ./main
      Hello world! - 1008
      

      基本上,无论您使用什么编译器,让它生成遵循其约定的相似/简单代码,然后模仿。

      注意,我使用的gcc不一定和你运行的一样,但过程是一样的。

      【讨论】:

        猜你喜欢
        • 2011-09-04
        • 1970-01-01
        • 2015-06-12
        • 1970-01-01
        • 1970-01-01
        • 2014-11-30
        • 2013-04-16
        • 2016-09-07
        • 2017-02-18
        相关资源
        最近更新 更多