将下面的所有代码每行详细的解释出来(2) reset: mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0 (3) ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] (4) relocate: adr r0, _start ldr r1, _TEXT_BASE cmp r0, r1 beq stack_setup ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 add r2, r0, r2 copy_loop: ldmia r0!, {r3-r10} stmia r1!, {r3-r10} cmp r0, r2 ble copy_loop (5) stack_setup: ldr r0, _TEXT_BASE sub r0, r0, #CFG_MALLOC_LEN sub r0, r0, #CFG_GBL_DATA_SIZE #ifdef CONFIG_USE_IRQ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 (6) clear_bss: ldr r0, _bss_start ldr r1, _bss_end mov r2, #0x00000000 clbss_l: str r2, [r0] add r0, r0, #4 cmp r0, r1 ble clbss_l
时间: 2024-02-05 13:04:41 浏览: 115
以下是对每行代码的详细解释:
2.
```
reset:
mrs r0,cpsr ; 将当前程序状态寄存器CPSR的值存储到寄存器r0中
bic r0,r0,#0x1f ; 将r0寄存器中的低5位清零
orr r0,r0,#0xd3 ; 将r0寄存器的低5位设置为11010011
msr cpsr,r0 ; 将修改后的值写入CPSR中
```
这段代码的作用是设置处理器的工作模式。首先将当前程序状态寄存器(CPSR)的值存储到寄存器r0中,接着将r0寄存器中的低5位清零,然后将r0寄存器的低5位设置为11010011,最后将修改后的值写入CPSR中,以设置处理器的工作模式。
3.
```
ldr r0, =pWTCON ; 将pWTCON的地址加载到r0寄存器中
mov r1, #0x0 ; 将常数0加载到r1寄存器中
str r1, [r0] ; 将r1寄存器中的内容存储到pWTCON指向的地址中
```
这段代码的作用是将常数0存储到一个特定的寄存器中。首先将pWTCON的地址加载到r0寄存器中,接着将常数0加载到r1寄存器中,最后将r1寄存器中的内容存储到pWTCON指向的地址中。
4.
```
relocate:
adr r0, _start ; 将_start的地址加载到r0寄存器中
ldr r1, _TEXT_BASE ; 将_TEXT_BASE的值加载到r1寄存器中
cmp r0, r1 ; 比较r0和r1寄存器中的值
beq stack_setup ; 如果相等则跳转到stack_setup标签处执行
ldr r2, _armboot_start ; 将_armboot_start的值加载到r2寄存器中
ldr r3, _bss_start ; 将_bss_start的值加载到r3寄存器中
sub r2, r3, r2 ; 计算_r2和_r3之间的偏移量
add r2, r0, r2 ; 计算r0和r2之间的偏移量
copy_loop:
ldmia r0!, {r3-r10} ; 从r0地址中读取r3到r10寄存器所存储的值
stmia r1!, {r3-r10} ; 将r3到r10寄存器所存储的值存储到r1地址中
cmp r0, r2 ; 比较r0和r2寄存器中的值
ble copy_loop ; 如果r0小于等于r2,则跳转到copy_loop标签处执行
```
这段代码的作用是将U-boot程序从一个位置复制到另一个位置。首先将_start的地址加载到r0寄存器中,将_TEXT_BASE的值加载到r1寄存器中,比较r0和r1寄存器中的值,如果相等则跳转到stack_setup标签处执行;如果不相等,则将_armboot_start的值加载到r2寄存器中,将_bss_start的值加载到r3寄存器中,计算_r2和_r3之间的偏移量,计算r0和r2之间的偏移量,然后从r0地址中读取r3到r10寄存器所存储的值,将r3到r10寄存器所存储的值存储到r1地址中,最后比较r0和r2寄存器中的值,如果r0小于等于r2,则跳转到copy_loop标签处执行。
5.
```
stack_setup:
ldr r0, _TEXT_BASE ; 将_TEXT_BASE的值加载到r0寄存器中
sub r0, r0, #CFG_MALLOC_LEN ; CFG_MALLOC_LEN减去r0的值
sub r0, r0, #CFG_GBL_DATA_SIZE ; CFG_GBL_DATA_SIZE减去r0的值
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) ; CONFIG_STACKSIZE_IRQ和CONFIG_STACKSIZE_FIQ的和减去r0的值
#endif
sub sp, r0, #12 ; 将r0减去常数12的结果存储到堆栈指针(sp)寄存器中
```
这段代码的作用是初始化堆栈指针。首先将_TEXT_BASE的值加载到r0寄存器中,然后将CFG_MALLOC_LEN减去r0的值,将CFG_GBL_DATA_SIZE减去r0的值,如果定义了CONFIG_USE_IRQ,则将CONFIG_STACKSIZE_IRQ和CONFIG_STACKSIZE_FIQ的和减去r0的值,最后将r0减去常数12的结果存储到堆栈指针(sp)寄存器中,以初始化堆栈指针。
6.
```
clear_bss:
ldr r0, _bss_start ; 将_bss_start的值加载到r0寄存器中
ldr r1, _bss_end ; 将_bss_end的值加载到r1寄存器中
mov r2, #0x00000000 ; 将常数0x00000000加载到r2寄存器中
clbss_l:
str r2, [r0] ; 将r2寄存器中的值存储到r0地址中
add r0, r0, #4 ; r0加上常数4
cmp r0, r1 ; 比较r0和r1寄存器中的值
ble clbss_l ; 如果r0小于等于r1,则跳转到clbss_l标签处执行
```
这段代码的作用是清空.bss段。首先将_bss_start的值加载到r0寄存器中,将_bss_end的值加载到r1寄存器中,将常数0x00000000加载到r2寄存器中,然后将r2寄存器中的值存储到r0地址中,r0加上常数4,比较r0和r1寄存器中的值,如果r0小于等于r1,则跳转到clbss_l标签处执行。
阅读全文