我有这个测试文件:
extern long int VALUE;
extern int *vMEMORY;
void main() {
(*vMEMORY) = VALUE;
} 我需要它的arm汇编代码,所以我使用以下代码:
arm-linux-gnueabi-gcc -S -march=armv4 test.c我得到了以下文件test.s:
.arch armv4
.eabi_attribute 27, 3
.fpu vfpv3-d16
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 34, 0
.eabi_attribute 18, 4
.file "test.c"
.text
.align 2
.global main
.type main, %function
main:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
str fp, [sp, #-4]!
add fp, sp, #0
ldr r3, .L2
ldr r3, [r3, #0]
ldr r2, .L2+4
ldr r2, [r2, #0]
str r2, [r3, #0]
add sp, fp, #0
ldmfd sp!, {fp}
bx lr
.L3:
.align 2
.L2:
.word vMEMORY
.word VALUE
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",%progbits我想将此test.s代码更改为C函数中的内联汇编代码。但我不知道该怎么做。我试过了:
asm volatile (
"ldr r3, %0\n"
"ldr r3, [r3, #0]\n"
"ldr r2, %1\n"
"ldr r2, [r2, #0]\n"
"str r2, [r3, #0]\n"
: "=r" (*vMEMORY)
: "r" (VALUE)
: "r2", "r3"
);但是,当我编译C函数时,我得到了以下错误:
/tmp/cckOasvT.s:汇编消息:
/tmp/cckOasvT.s:254: Error: internal_relocation (类型: OFFSET_IMM)未修复
/tmp/cckOasvT.s:256: Error: internal_relocation (类型: OFFSET_IMM)未修复
有没有人可以帮我解决这个错误,或者告诉我应该如何修改代码?
发布于 2015-10-27 23:24:45
我认为第254和256行对应于:
"ldr r3, %0\n"
...
"ldr r2, %1\n"在这两种情况下,您都试图将一个立即值加载到寄存器中(第一次是vMEMORY的地址,第二次是VALUE的地址)。这两个常量都太大(32位),无法放入指令的立即字段(10位?我不确定)。编译器试图通过编码期望地址和程序计数器之间的差异(偏移量)来解决这个问题,但仍然失败,因此出现了错误消息。
一种解决方案是将vMEMORY和VALUE声明为局部变量:这将允许编译器将它们放在离函数体更近的地方,从而减少偏移量。
另一种解决方案是像编译器对原始C代码所做的那样-创建包含vMEMORY和VALUE地址的本地变量,并在以后使用额外的load指令来消除间接性。
https://stackoverflow.com/questions/23006603
复制相似问题