结合c和汇编代码

时间:2014-12-13 22:44:42

标签: 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

我试图从我的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

1 个答案:

答案 0 :(得分:5)

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

movq %rax, _newAlphabet

为:

mov %eax, _newAlphabet(%rip)

并且你将被设置(我在Mac OS X上从64位更改为32位寄存器以匹配sizeof(int)。请注意,在某处你还需要.globl _newAlphabet。这里&#39 ;我刚刚根据您的代码制作的一个示例(请注意,我已初始化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;
}

assembly.s:

.globl _sum
.globl _newAlphabet

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

Build&amp;运行:

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