结合c和汇编代码

Sim*_*ans 2 c macos assembly gcc x86-64

这是我的C代码:

#include <stdio.h>

    void sum();
    int newAlphabet;
    int main(void)
    {
        sum();
        printf("%d\n",newAlphabet);
    }
Run Code Online (Sandbox Code Playgroud)

这是我的汇编程序代码:

.globl _sum

_sum:
    movq $1, %rax
    movq %rax, _newAlphabet
    ret
Run Code Online (Sandbox Code Playgroud)

我正在尝试从我的main函数调用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"

我确定我犯的是一个非常基本的错误.有人可以帮忙吗?提前致谢.

编辑:

以下是C代码转换为汇编程序后的相关部分:

.comm   _newAlphabet,4,2
...
movq    _newAlphabet@GOTPCREL(%rip), %rax
Run Code Online (Sandbox Code Playgroud)

Car*_*rum 5

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

movq %rax, _newAlphabet
Run Code Online (Sandbox Code Playgroud)

至:

mov %eax, _newAlphabet(%rip)
Run Code Online (Sandbox Code Playgroud)

并且你将被设置(我在64位寄存器中更改为sizeof(int)在Mac OS X上匹配.请注意,你还需要.globl _newAlphabet在某处.这是我刚刚根据你的代码制作的一个例子(请注意我初始化newAlphabet以证明它作品):

example.c:

#include <stdio.h>

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

assembly.s:

.globl _sum
.globl _newAlphabet

_sum:
    movl $1, _newAlphabet(%rip)
    ret
Run Code Online (Sandbox Code Playgroud)

构建和运行:

$ cc -c -o example.o example.c
$ cc -c -o assembly.o assembly.s
$ cc -o example example.o assembly.o
$ ./example
2
1
Run Code Online (Sandbox Code Playgroud)