结合 C 和汇编代码

标签 c macos gcc assembly x86-64

这是我的 C 代码:

#include <stdio.h>

    void sum();
    int newAlphabet;
    int main(void)
    {
        sum();
        printf("%d\n",newAlphabet);
    }

这是我的汇编代码:

.globl _sum

_sum:
    movq $1, %rax
    movq %rax, _newAlphabet
    ret

我试图从我的主函数中调用 sum 函数来设置 newAlphabet等于 1,但是当我编译它时( gcc -o test assembler.c assembler.s ,在 64 位 OSX 笔记本电脑上编译),我收到以下错误:

32-bit absolute addressing is not supported for x86-64

cannot do signed 4 byte relocation

both caused by the line "movq %rax, _newAlphabet"

I'm sure I'm making a very basic mistake. Can anyone help? Thanks in advance.

EDIT:

Here are the relevant portions of the C code once it has been translated to assembler:

.comm   _newAlphabet,4,2
...
movq    _newAlphabet@GOTPCREL(%rip), %rax

最佳答案

Mac OS X 默认使用位置无关的可执行文件,这意味着您的代码不能使用变量的常量全局地址。相反,您需要以与 IP 相关的方式访问全局变量。只需更改:

movq %rax, _newAlphabet

至:

mov %eax, _newAlphabet(%rip)

然后您就完成了设置(我将寄存器从 64 位更改为 32 位,以匹配 Mac OS X 上的 sizeof(int)。请注意,您还需要一个 .globl _newAlphabet code> 在那里某处。这是我刚刚根据您的代码制作的示例(请注意,我初始化了 newAlphabet 以证明它有效):

示例.c:

#include <stdio.h>

void sum(void);
int newAlphabet = 2;
int main(void)
{
    printf("%d\n",newAlphabet);
    sum();
    printf("%d\n",newAlphabet);
    return 0;
}

程序集:

.globl _sum
.globl _newAlphabet

_sum:
    movl $1, _newAlphabet(%rip)
    ret

构建并运行:

$ cc -c -o example.o example.c
$ cc -c -o assembly.o assembly.s
$ cc -o example example.o assembly.o
$ ./example
2
1

关于结合 C 和汇编代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27464437/

相关文章:

c - 使用 scanf 读取字符串然后读取整数,只读取字符串

c - 我的进程仍然是守护进程吗?

c++ - 在MAC OS X上的CMAKE项目中包含标记(ncurses)

linux -/usr/local/lib 的 OS X 权限被拒绝

C - PGM 和 PPM - 动态分配表,图像切成两半

c++ - 统一影响着色器流程和性能

linux - linux shell 和 macos shell 有什么区别?

c - gcc -W -Wall -O -pedantic -std=c99 与具有相同选项的 clang

java - 如何从 JNI 的现有 c 项目 (concorde) 创建 .dylib

gcc - ARM 程序集 : . LANCHOR0