1、ldr r0, =0x4c000004
(1)对应的反汇编
33f80024:e59f0084 ldrr0, [pc, #132] ; 33f800b0 <sdram_config+0x38>
33f80024是运行地址
e59f0084是机器码
ldrr0, [pc, #132]是汇编指令编译时执行的指令
33f800b0是PC+132得出的地址
<sdram_config+0x38>表示偏移函数sdram_config的0x38处
(2)分析
如果对于ldr伪汇编指令,0x4c000004这个数比较复杂,不能用mov指令表示,会吧这个数存在地址(pc + 132)处,也就是33f800b0处,然后从(pc + 132)的存储器地址处取出数据,加载到寄存器r0中。
33f800b0: 4c000004stcmi 0, cr0, [r0], {4}
2、adr r1, sdram_config
(1)对应的反汇编
r1等于当前PC+60,60就是0x3c.如果是从0地址开始运行,当前PC等于当前地址0x33f80034加8,再加上0x3c,等于33f80078
33f80034: e28f103cadd r1, pc, #60; 0x3c
(2)分析
3f80078是函数sdram_config的链接地址
3f80078 <sdram_config>:
3、ldr r1, =_start和ldr r2, =__bss_start
(1)对应的反汇编
r1是目标地址,也是运行地址,其值在33f800b8,因为33f800b8:33f80000 mvnccsr0, #0 ; 0x0,因而可知运行地址r1等于33f80000,33f80000是链接脚本指定的起始地址
33f80058:e59f1058 ldrr1, [pc, #88] ; 33f800b8 <sdram_config+0x40>
r2对应的是长度,其值在33f800bc处,因为33f800bc:33f806b0 mvnccsr0, #184549376 ; 0xb00000。因而可知r2等于33f806b0
33f8005c: e59f2058 ldr r2, [pc, #88]; 33f800bc <sdram_config+0x44>
r2的最终结果是33f806b0-33f80000,也就是0x6b0,十进制是1712(因为向4对齐,在boot.lds内加了ALIGN(4)),就是我们要拷贝的文件大小,查看编译出来的boot.bin文件
3f80060:e0422001 subr2, r2, r1、
4、C语言
(1)源程序
//清除bss段
void clear_bss(void)
{
把__bss_start, __bss_end定义为外部的整型变量
extern int __bss_start, __bss_end;
定义指针指向bss段的首地址
int *p = &__bss_start;循环把bss段中变量赋为0,直到bss段的结尾
for (; p < &__bss_end; p++)
*p = 0;
}
(2)对应汇编
__bss_start取地址为33f80118的值, __bss_end取地址为33f8011c 的值
33f800f4:e59f301c ldrr3, [pc, #28] ; 33f80118 <.text+0x118>
33f800f8: e59f101c ldr r1, [pc, #28]; 33f8011c <.text+0x11c>
地址为33f80118的值为33f806b0 , 地址为33f8011c 的值为33f806b4
33f80118:33f806b0 mvnccsr0, #184549376 ; 0xb000000
33f8011c: 33f806b4 mvnccs r0, #188743680; 0xb400000
从上面可知bss段只有4字节(33f806b4- 33f806b0,__bss_end-__bss_start),这4字节是
bss段的反汇编只有变量params,初始值为0,并没有存在二进制文件里面,让变量初始值为0,要通过清除bss操作
Disassembly of section .bss:
33f806b0 <params>:
33f806b0: 00000000 andeq r0, r0, r0