百度网盘源码文件:
/* Peri port setup
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4
@ 256M(0x70000000-0x7fffffff)
链接地址:程序访问全局变量时用的是它的链接地址
1.程序运行时,“应该”位于的它的链接地址
2.硬件决定了程序一开始从0地址运行,需要重定位:前面一小段代码把程序复制到链接地址
每个程序都有三个段:代码段、数据段、BSS段。
代码段:存放指令。
数据段:存放有初始化且不为0的全局/静态变量
BSS段:存放初始值为0或无初始值的全局/静态变量
编译出的二进制文件不包含BSS段(假如一个程序中有10000个值为0的全局变量,若将BSS段也编译进二进制文件,那岂不是很大,而且这些变量还不一定会用到,故程序不会将BSS段编译进二进制文件内)
位置无关码:跳转用B或BL,不访问全局/静态变量的代码
链接脚本:
SECTIONS
/SECTION代表段,S为多个段
{
. = 0x1000;
/指定链接地址为0x1000,和之前用Makefile中的-Ttext 0 指定的链接地址是一个意思
.text : {
/.text代码段的排列顺序,先放start.o然后是各个文件中的代码段
start.o
* (.text)
}
.data : {
/.data 数据段 排放各个文件中的数据段
* (.data)
}
bss_start = .;
/指定BSS段的开始为当前地址(即上面各个段排放后的地址)
.bss : {
* (.bss)
}
bss_end
= .; /指定BSS段的结束地址为当前
}
文件名:start.S
.globl _start
_start:
/* 硬件相关的设置
/* 关看门狗
/* 往WTCON(0x7E004000)写0
ldr r0, =0x7E004000
mov r1, #0
str r1, [r0]
/* 重定位
adr r0, _start
/* 伪指令,取_start的当前地址
ldr r1, =_start /* 链接地址
ldr r2, =bss_start
cmp r0, r1
beq clean_bss
copy_loop:
/将程序复制到其链接地址
ldr r3, [r0], #4
str r3, [r1], #4
cmp r1, r2
bne copy_loop
/* 清bss段
clean_bss:
ldr r0, =bss_start
ldr r1, =bss_endmov r2, #0
clean_loop:
str r2, [r0], #4
cmp r0, r1
bne clean_loop
/* 设置栈
ldr sp, =8*1024
ldr pc, =main
bl main
halt:
b halt