这是某哥们发的,是44B0上的,说的比较让人迷糊:
;========================================================
;========================================================
;注:以下这一小段代码还是在ROM中执行的,但这一小段代码却完成了非常重要的功能,完成的功能如下
;1:判断加载域和运行域是否相同,如果不同,那么要把"拷贝程序模板"事先复制到运行域中去,然后跳转到运行域,
;再把ROM中的代码拷贝到
;RAM中去,为什么要这样,因为ARM的程序在ROM中执行的时候,不能再读取ROM中的数据,然后写入到RAM中去,只能把完成拷贝功能
;的那一小部分代码先拷贝到RAM中去,然后跳转到RAM中,执行从ROM中读取数据,然后将读到的数据拷贝到RAM中去这样的操作。
;====================================================
;拷贝并粘贴 RW data/zero initialized data
;====================================================
adr r0, ResetEntry ;R0中装入ResetEntry,注意,adr这条指令是个伪指令,也即加载域首地址,理解这条指令很关键,弄不好要看汇编后的代码,。,,
ldr r1, BaseOfROM ;R1中装入BaseOfROM,BaseOfROM为运行域首地址
cmp r0, r1 ;比较R0和R1是否相等,也就是比较加载域地址和运行域地址是否相同
ldreq r0, TopOfROM
beq InitRamData ;如果相等,则跳转到InitRamData
;====================================================
;计算拷贝程序在flash中的实际位置
;====================================================
ldr r2, =CopyProcBeg ;将CopyProcBeg装入到R2,CopyProcBeg为代码拷贝的首地址
sub r1, r2, r1 ; r1 = r2 - r1,这里因为CopyProcBeg标号和BaseOfROM标号有个偏差,而我们要把
;烧录到ROM中CopyProcBeg处的一段代码拷贝到BaseOfROM为起始地址处,但CopyProcBeg
add r0, r0, r1 ;r0 = r0 + r1,这句话实际上是得出加载域中CopyProcBeg的地址
ldr r3, =CopyProcEnd ;r3 = CopyProcEnd
;====================================================
;将拷贝程序复制到ram中
;====================================================
0
ldmia r0!, {r4-r7} ;将加载域中的值装入到R4-R7,并且加载域地址指针自增
stmia r2!, {r4-r7} ;将R4-7中的值装入到R2所指的一段内存处,并且运行域地址指针自增。
cmp r2, r3 ;判断是否拷贝结束
bcc %B0
;====================================================
;开始用ram中的拷贝程序复本将所有剩下的代码复制到ram中
;====================================================
ldr r3, TopOfROM ;将RO段的数据长度装入到R3
ldr pc, =CopyProcBeg ;将PC指针指向CopyProcBeg,注意这以后的程序就是在RAM中运行了
;=========================================================
;=========================================================
;=========================================================
;以下程序在RAM中执行了!
;=========================================================
;=========================================================
;本段将代码由实际烧入的地址拷贝到ro-base所指定的位置
;只拷贝CopyProcEnd以后的代码
;这段代码是将RO段代码由加载域拷贝到运行域中去
;=========================================================
CopyProcBeg
0
ldmia r0!, {r4-r11} ;将加载域中的值装入到R4-R7,并且加载域地址指针自增
stmia r2!, {r4-r11} ;将R4-7中的值装入到R2所指的一段内存处,并且运行域地址指针自增。
cmp r2, r3 ;判断是否将RO段的代码完全从加载域拷贝到运行域,如果没拷贝完则继续拷贝
bcc %B0
CopyProcEnd
;此处则说明RO段代码已经拷贝完成,那么接下来要将RW段的数据从加载域拷贝到运行域
sub r1, r2, r3
sub r0, r0, r1 ;这里应该是进行字节对齐的处理。以免少拷贝几个字节的东西。
;=========================================================
;这段代码是将RW段代码由加载域拷贝到运行域中去
;=========================================================
InitRamData
ldr r2, BaseOfBSS ;RW段首地址
ldr r3, BaseOfZero ;RW段长度
0
cmp r2, r3 ;判断是否将RW段的代码完全从加载域拷贝到运行域,如果没拷贝完则继续拷贝
ldrcc r1, [r0], #4 ;将R0所指单元的数据拷贝到R1中
strcc r1, [r2], #4 ;将R1中的数据复制到R2所指单元中去
bcc %B0
;=========================================================
;这段代码是将ZI段数据清零
;=========================================================
mov r0, #0
ldr r3, EndOfBSS ;将ZI段数据结束地址装入R3,用以判断ZI段是否清零结束
1
cmp r2, r3 ;判断ZI段是否结束,如果未结束,还要继续清零内存
strcc r0, [r2], #4 ;将R2所指单元的内容清零
bcc %B1
直接使用1楼的代码实际测试是可以运行的,难道2440和44B0的NOR代码搬运有区别?