c - 内联汇编 --> 错误 : internal_relocation (type: OFFSET_IMM) not fixed up

标签 c assembly label inline-assembly

我有这个测试文件:

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:错误:internal_relocation(类型:OFFSET_IMM)未修复

/tmp/cckOasvT.s:256: 错误:internal_relocation(类型:OFFSET_IMM)未修复

谁能帮我解决错误或告诉我应该如何更改代码?

最佳答案

我想第 254 行和第 256 行对应于:

 "ldr   r3, %0\n"
 ...
 "ldr   r2, %1\n"

在这两种情况下,您都试图将立即值加载到寄存器中(第一次是 vMEMORY 的地址,第二次是 VALUE 的地址)。这两个常量都太大(32 位)以适应指令的直接字段(10 位?我不确定)。编译器试图通过对所需地址和程序计数器之间的差异 (OFFSET) 进行编码来解决此问题,但仍然失败,因此出现错误消息。

一个解决方案是声明 vMEMORYVALUE作为局部变量:这将允许编译器将它们放置在更靠近函数体的位置,从而减少偏移量。

另一种解决方案是执行编译器对原始 C 代码执行的操作 - 创建包含地址 vMEMORY 的局部变量和 VALUE ,并使用额外的加载指令稍后摆脱间接寻址。

关于c - 内联汇编 --> 错误 : internal_relocation (type: OFFSET_IMM) not fixed up,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23006603/

相关文章:

python - 将图像添加到 pyplot 中的 ylabel

c# - 根据内容的宽度调整标签宽度

c - 每个中断处理程序都需要自旋锁吗?

c - rand() 在我的自定义函数中不返回任何值

c++ - 将这些 C++ 行转换为汇编/mips 时,我做错了什么?

c - 汇编中保留的堆栈空间似乎与 C 代码不匹配

c - 使用 fopen 的追加模式覆盖文件

c - 在不知道结构大小的情况下在结构中声明二维数组?

linux - x86 ASM Linux - 使用 .bss 部分

java - 如何更改点击时的标签颜色?