难度:★★
本文首发于我的嵌入式技术号「OneChan」,未经授权禁止转载。
你正编译一个工程,汇编器突然甩给你一行红字:
Error: A1586E: Bad operand (literal pool is too far away)或者:
Error: L6248E: Relocation #REL:0 in startup.o(.text) is out of range你仔细检查了代码,语法完全正确。你删掉几行代码再编译,错误消失。加上那几行代码,错误又回来了。
这不是语法错误。这是“物理距离”错误。
你的代码在物理上太远了——一条指令够不到它想访问的那个常数。
今天这篇文章,就来拆开 ARM 汇编里最反直觉的编译错误。它的根源,是 32 位指令编码里那几个不起眼的位字段,以及设计者们在“指令宽度”和“寻址范围”之间做出的一个艰难取舍。
一、先看现象:什么时候会爆这个错误?
场景一:LDR =的文字池太远
LDR R0, =0x12345678 ; 第 1 行 ; 中间是 5000 字节的大段代码 ; ... ; 段末尾在这里,距离第