连接地址与位置无关指令

在点灯程序中,想看看超过地址空间的结果,于是做了个试验,修改Makefile中的连接地址为0xfffffffc,如下所示。
root@ubuntu:~/work/led_on_c# cat Makefile
all:
arm-linux-gcc -c -o led.o led.c
arm-linux-gcc -c -o start.o start.S
arm-linux-ld -Ttext 0xfffffffc start.o led.o -o led.elf
arm-linux-objcopy -O binary -S led.elf led.bin
arm-linux-objdump -D led.elf > led.dis
clean:
rm *.bin *.o *.elf *.dis
编译烧写到NAND中,复位后指示灯仍然能点亮。我认为超过地址空间了cpu就找不到程序执行的地址了,那它就不能正常工作啊,但是实验结果是它还能正常工作,感觉很奇怪,于是打开反汇编代码,如下所示:
fffffffc <_start>:
fffc: e3a0da01 mov sp, #4096 ; 0x1000
0: Address 0x0 is out of bounds.

Disassembly of section .comment:

00000000 <.comment>:
0: 43434700 cmpmi r3, #0 ; 0x0
4: 4728203a undefined
8: 2029554e eorcs r5, r9, lr, asr #10
c: 2e342e33 mrccs 14, 1, r2, cr4, cr3, {1}
10: Address 0x10 is out of bounds.
如上所示,反汇编有效代码只有2行,这是符合我的预期的。但是为什么还是能正常执行呢?通过查找资料,有一种说法我认为很有道理,记录下来。如下:
位置无关指令(比如这里用的 bl xxxx 就是位置无关指令)是将PC加上(或减去)绝对偏移值得到实际指令的地址,再跳到这个地址去执行,它不会管代码被连接后指令应该在的地址,也不管程序当前位置处于rom还是ram,它只会加上偏移值(如这里是PC+8后跳到main处执行)。而位置相关指令(如ldr指令)它是相对偏移,它会将连接地址赋给PC,PC再跳到连接地址处去执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值