难度:★★本文首发于我的嵌入式技术号「OneChan」,未经授权禁止转载。翻开任何一段嵌入式汇编代码,你大概率会看到这样的写法:LDR R0, =SystemInit LDR R1, =0x20001000 LDR R2, =g_counter那个等号=,是初学者最容易困惑的地方。它看起来像赋值,又像取地址,很多人用了很多年也没搞清楚它到底是什么。今天,我们就把这个=彻底拆开。你会发现,它根本不是一条指令,而是一个请汇编器帮忙的“代购请求”。而这个机制存在的理由,牵出了 ARM 指令集最核心的一条物理限制——以及工具链为了绕过这个限制而发明的精巧设计:文字池。一、为什么 MOV 不能直接加载任意值?答案就一句话:ARM 指令是定长 32 位的,没有足够的空间塞下一个完整的 32 位立即数。ARM 和 Thumb-2 的指令编码,每一条指令都是 32 位宽。其中有一部分位用来放操作码,一部分位用来放寄存器编号,还有一部分位用来放条件码和其他控制字段。真正能分配给“立即数”的宽度,只有12 位左右。12 位只能表示 0 到 4095。那怎么加载0x20001000这