简体   繁体   English

在Arm组件中使用C中声明的全局变量

[英]Using global variables declared in C, in Arm assembly

I have a C file which declares a global variables. 我有一个声明全局变量的C文件。 This file will be compiled together with some ARM assembly files. 此文件将与一些ARM程序集文件一起编译。

int foo;

void call_asm(void);

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

I tried using the link from the arm infocenter but the compiler ( arm-linux-gnueabi-gcc ) is telling me that "import" is an undefined instruction. 我尝试使用arm信息中心链接,但编译器( arm-linux-gnueabi-gcc )告诉我“import”是一个未定义的指令。

Can I simply do something like: 我可以简单地做一些事情:

LDR    r0, =GLOBAL_VAR

How can I use the global variables defined in the C file in assembly? 如何在程序集中使用C文件中定义的全局变量?

This becomes quite simple once you ask gcc how to do it. 一旦你问gcc怎么做,这就变得非常简单了。 For example, compile the following function with gcc -S -O3 : 例如,使用gcc -S -O3编译以下函数:

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

You'll see how gcc implements it. 你会看到gcc如何实现它。

Based on this, I've devised a working example of calling an assembly function from C to set a global C variable: 基于此,我设计了一个从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

Compilation and running: 编译和运行:

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

Tested on gcc Raspbian 6.3.0-18+rpi1. 测试了gcc Raspbian 6.3.0-18 + rpi1。

That assembly code above was based on the gcc output for the useFoo example. 上面的汇编代码基于useFoo示例的gcc输出。 A simpler way is to use =foo instead of manually placing the address to a variable: 更简单的方法是使用=foo而不是手动将地址放入变量:

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

This will result in the address of foo being put after the function definition by the assembler. 这将导致foo的地址被汇编器放在函数定义之后。

I think you need to translate the directives from the ARM assembler to the GNU assembler. 我认为您需要将指令从ARM汇编程序转换为GNU汇编程序。 If I understand correctly, you can access any global symbol by using the .global directive instead of .import . 如果我理解正确,您可以使用.global指令而不是.import访问任何全局符号。 From the Using as pages: 使用为页面:

.global symbol .global 符号

.global makes the symbol visible to ld. .global使符号对ld可见。 If you define symbol in your partial program, its value is made available to other partial programs that are linked with it. 如果在部分程序中定义符号 ,则其值可用于与其链接的其他部分程序。 Otherwise, symbol takes its attributes from a symbol of the same name from another file linked into the same program. 否则, 符号从链接到同一程序的另一个文件中获取同名符号的属性。

.extern (symbol)

是你需要的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM