比如 xboot 这个代码段重定位 https://github.com/xboot/xboot/blob/master/src/arch/arm32/mach-f1c100s/start.S
_speedup:
nop
/* Copyself to link address */
adr r0, _start
ldr r1, =_start
cmp r0, r1
beq 1f
bl sys_copyself
第一条语句 adr r0, _start 编译后是 基于PC指针把 _start 的位置读到 r0 寄存器,
在哪个位置运行, r0 值就是多少. 比如程序在 0x800 运行, 那么 _start 就是 0x800
第二条语句 ldr r1, =_start 是取 _start 的链接地址, 也就是重定位地址.
如果 r1 与 r0 寄存器不相等, 他们肯定要进行重定位 (代码段复制)
为了证明这个问题, 我用MDK反汇编看了一下:
离线
离线
/* Copyself to link address */
la t0, _start
la t1, _image_start
LREG t1, (t1)
beq t0, t1, 1f
la a0, _image_start
LREG a0, (a0)
la a2, _image_end
LREG a2, (a2)
sub a2, a2, a0
la a1, _start
call memcpy
1: nop
贴一个riscv版本的
离线
/* Copyself to link address */ la t0, _start la t1, _image_start LREG t1, (t1) beq t0, t1, 1f la a0, _image_start LREG a0, (a0) la a2, _image_end LREG a2, (a2) sub a2, a2, a0 la a1, _start call memcpy 1: nop
贴一个riscv版本的
这一句没看懂, LREG t1, (t1)
哪位路过的大佬解释一下。
离线