我想在内联手臂组件中访问C中声明的局部变量。我该怎么做?
可以像这样访问全局变量,
int temp = 0;
Function(){
__asm(
".global temp\n\t"
"LDR R2, =temp\n\t"
"LDR R2, [R2, #0]\n\t"
);
}
但是如何访问局部变量?我试着改变" .global" to" .local"对于局部变量,但它产生了错误(未定义引用`temp')。 我使用的IDE是KEIL。
有什么想法? 在此先感谢。
答案 0 :(得分:5)
根据GCC文件:6.45.2.3 Output Operands
您可以传递如下值:
#include <stdio.h>
int main(int argc, char *argv[]) {
int src = 1;
int dst;
asm ("mov %1, %0\n\t add $1, %0" : "=r" (dst) : "r" (src));
printf("0x%X\n", dst);
return 0;
}
在您的asm代码之后,您将':'
字符和要传递的值放在这样的位置:"(=|+)(r|m)" (variable)
。在覆盖值时使用'='
,在读取或覆盖值时使用'+'
,如果值位于寄存器中,则使用'r'
字母;如果值驻留在内存中,则使用'm'
答案 1 :(得分:1)
r
最小可运行示例
main.c
#include <assert.h>
#include <inttypes.h>
int main(void) {
uint64_t in0 = 1, in1 = 2, out;
__asm__ (
"add %[out], %[in0], %[in1];"
: [out] "=r" (out)
: [in0] "r" (in0),
[in1] "r" (in1)
);
assert(in0 == 1);
assert(in1 == 2);
assert(out == 3);
}
编译并运行:
sudo apt-get install qemu-user gcc-aarch64-linux-gnu
aarch64-linux-gnu-gcc -std=c99 -ggdb3 -march=armv8-a -pedantic -Wall -Wextra -o main.out main.c
qemu-aarch64 -L /usr/aarch64-linux-gnu -E LD_BIND_NOW=1 main.out
反汇编:
gdb-multiarch -nh -batch -ex 'disassemble/rs main' add.out
输出摘录:
Dump of assembler code for function main:
add.c:
6 int main(void) {
0x0000000000000764 <+0>: fd 7b bd a9 stp x29, x30, [sp, #-48]!
0x0000000000000768 <+4>: fd 03 00 91 mov x29, sp
7 uint64_t in0 = 1, in1 = 2, out;
0x000000000000076c <+8>: 20 00 80 d2 mov x0, #0x1 // #1
0x0000000000000770 <+12>: e0 0f 00 f9 str x0, [sp, #24]
0x0000000000000774 <+16>: 40 00 80 d2 mov x0, #0x2 // #2
0x0000000000000778 <+20>: e0 13 00 f9 str x0, [sp, #32]
8 __asm__ (
0x000000000000077c <+24>: e0 0f 40 f9 ldr x0, [sp, #24]
0x0000000000000780 <+28>: e1 13 40 f9 ldr x1, [sp, #32]
0x0000000000000784 <+32>: 00 00 01 8b add x0, x0, x1
0x0000000000000788 <+36>: e0 17 00 f9 str x0, [sp, #40]
9 "add %[out], %[in0], %[in1];"
10 : [out] "=r" (out)
11 : [in0] "r" (in0),
12 [in1] "r" (in1)
13 );
因此,我们看到r
转换为堆栈sp
相对str
的负载,这是局部变量所在的位置。
在Ubuntu 18.10,GCC 8.2.0,QEMU 2.12中进行了测试。