难度:★★
本文首发于我的嵌入式技术号「OneChan」,未经授权禁止转载。
先看两行代码:
LDR R0, =Reset_Handler ; ① DCD Reset_Handler ; ②它们都引用了同一个标号Reset_Handler。
但用反汇编器查看,你会发现一个诡异的现象:
- ① 变成了一条
LDR R0, [PC, #offset]——PC 相对寻址。 - ② 变成了一个硬邦邦的 32 位立即数,比如
0x08000101——绝对地址。
同一个标号,为什么一会儿是相对的,一会儿是绝对的?
更诡异的是:如果你把这段代码从 Flash 挪到 RAM 里运行,① 可能还能跑,② 直接炸。
今天这篇文章,就来拆开标号在不同上下文里的“双重人格”,看看汇编器和链接器如何决定把一个标号变成相对地址还是绝对地址,以及这个决定在运行时会怎样影响你的程序。
一、标号本身没有“绝对”或“相对”的属性
先说清楚第一个误区。
Reset_Handler这