Using global variables declared in C, in Arm assembly

12,618

Solution 1

This becomes quite simple once you ask gcc how to do it. For example, compile the following function with gcc -S -O3:

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

You'll see how gcc implements it.

Based on this, I've devised a working example of calling an assembly function from C to set a global C variable:

// 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.

That assembly code above was based on the gcc output for the useFoo example. A simpler way is to use =foo instead of manually placing the address to a variable:

# 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.

Solution 2

.extern (symbol)

is what you need

Share:
12,618
de1337ed
Author by

de1337ed

Updated on June 11, 2022

Comments

  • de1337ed
    de1337ed almost 2 years

    I have a C file which declares a global variables. This file will be compiled together with some ARM assembly files.

    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.

    Can I simply do something like:

    LDR    r0, =GLOBAL_VAR
    

    How can I use the global variables defined in the C file in assembly?