7

我有一个声明全局变量的 C 文件。该文件将与一些 ARM 汇编文件一起编译。

int foo;

void call_asm(void);

int main(void) {
    call_asm();
    return foo;
}
call_asm:
    ...

我尝试使用来自 arm 信息中心的链接,但编译器 ( arm-linux-gnueabi-gcc) 告诉我“导入”是未定义的指令。

我可以简单地做类似的事情:

LDR    r0, =GLOBAL_VAR

如何在汇编中使用 C 文件中定义的全局变量?

4

3 回答 3

4

一旦你问 gcc 如何做到这一点,这变得非常简单。例如,使用 编译以下函数gcc -S -O3

extern int foo;
void useFoo()
{
    foo=7;
}

您将看到 gcc 如何实现它。

基于此,我设计了一个从 C 调用汇编函数来设置全局 C 变量的工作示例:

// test.c
#include <stdio.h>

void setupFoo();
int foo;

int main()
{
    setupFoo();
    printf("foo=%d\n", foo);
}
# test.s
.text
.global foo
.fooAddr:
    .word foo

.global setupFoo
setupFoo:
    ldr r0, .fooAddr
    mov r1, #123
    str r1, [r0]
    bx lr

编译和运行:

$ gcc test.c test.s -o test && ./test
foo=123

在 gcc Raspbian 6.3.0-18+rpi1 上测试。

上面的汇编代码基于useFoo示例的 gcc 输出。一种更简单的方法是使用=foo而不是手动将地址放置到变量中:

# test.s
.text
.global foo
.global setupFoo
setupFoo:
    ldr r0, =foo
    mov r1, #123
    str r1, [r0]
    bx lr

这将导致foo汇编器将地址放在函数定义之后。

于 2019-04-01T10:03:34.587 回答
2

我认为您需要将指令从 ARM 汇编器转换为 GNU 汇编器。如果我理解正确,您可以使用.global指令而不是.import. 从用作页面:

.global符号

.global 使符号对 ld 可见。如果您在部分程序中定义符号,则其值可用于与其链接的其他部分程序。否则,符号从链接到同一程序的另一个文件的同名符号中获取其属性。

于 2012-11-01T17:59:28.340 回答
2
.extern (symbol)

是你需要的

于 2017-05-22T14:43:36.403 回答