ARM汇编 启动代码
1.目的
arm汇编的主要目的是为了编写arm启动代码,启动代码启动以后,引导程序到c语言环境下运行。换句话说启动代码的目的是为了在处理器复位以后搭建c语言最基本的需求。因此启动代码的主要任务有:
1、初始化异常向量表;
2、初始化各工作模式的栈指针寄存器;
3、开启arm内核中断允许;
4、将工作模式设置为user模式;
5、完成上述工作后,引导程序进入c语言主函数执行
2.初始化异常向量表
preserve8area reset, code, readonlycode32entryldr pc, =start_handlerldr pc, =undefine_handlerldr pc, =software_handlerldr pc, =prefetch_handlerldr pc, =data_handlernopldr pc, =irq_handlerldr pc, =fiq_handlerundefine_handlerb undefine_handlersoftware_handlerimport software_vectorstmfd sp!, {r0-r12, lr} ;压栈bl software_vectorldmfd sp!, {r0-r12, pc}^ ;出栈,加^代表自动变换为原来的模式;bx lrprefetch_handlerb prefetch_handlerdata_handlerb data_handlerirq_handlerb irq_handlerfiq_handlerb fiq_handlerexport asm_swi_fun
asm_swi_funsvc #7bx lrstart_handlerldr sp, =0x40001000 ;设置栈底位置,注意为满减栈import mainmrs r0, cpsr ;从cpsr寄存器中读取值放到r0中bic r0, r0, #(0x1f<<0) ;先让低5位清0bic r0, r0, #(1<<7) ;打开中断orr r0, r0, #(0x10<<0) ;改变模式为user模式,即10000,故让bit4值1msr cpsr_c, r0 ;将r0中的值写入到cpsr寄存器中ldr sp, =0x40001000sub sp, sp, #1024 ;重新设置栈底位置,减去1k大小即1024个字节b main ;进入c语言的main函数中end
ldr pc程序计数器,使得各异常程序有了对应的地址
异常向量表:内核为每种异常在固定地址(向量表)中存放处理程序入口,发生异常时自动跳转到对应地址执行
3.初始化栈指针寄存器
由于ARM内核时满减栈,且所用板子为2440,IRAM起始地址为0x40000000,大小为0x1000,即4096个字节(4k大小),且为满减栈,故栈底设置为0x40001000,当要压栈时,栈针先自加后再赋值
4.相关指令
1.mrs
在 ARM 架构指令集中,MRS(Move from Special Register) 是一条用于读取特殊寄存器(Special Register)内容到通用寄存器的指令。它是访问 ARM 处理器特殊寄存器的关键指令,常用于获取处理器状态、配置信息等。
MRS <通用寄存器>, <特殊寄存器>
- 功能:将
<特殊寄存器>
的内容复制到<通用寄存器>
中。 - 特殊寄存器:cpsr当前程序状态寄存器,spsr:备份程序状态寄存器
MRS r0, CPSR ; 将当前程序状态寄存器(CPSR)的值读取到r0
2.msr
在 ARM 架构指令集中,MSR(Move to Special Register) 是与 MRS 指令对应的指令,用于将通用寄存器中的数据写入到特殊寄存器(Special Register)中。它主要用于修改处理器状态、配置系统控制参数等底层操作
MSR <特殊寄存器>{<字段>}, <通用寄存器>
功能:将<通用寄存器>
的内容写入<特殊寄存器>
的指定<字段>
(若不指定字段,则写入整个寄存器)
MRS r0, CPSR ; 先通过MRS读取CPSR到r0
ORR r0, r0, #0x80 ; 置位I位(bit7):0x80 = 10000000b
MSR CPSR_c, r0 ; 将修改后的控制字段写回CPSR
3.stmfd
STMFD <Rn>{!}, <寄存器列表>
- 功能:按照 “满递减栈(Full Descending Stack)” 的方式,将寄存器列表中的多个寄存器值依次存储到内存中。
- 参数说明:
<Rn>
:基址寄存器,通常为栈指针sp
(r13
),表示栈的当前位置。!
:可选的写回标志,若添加则指令执行后会自动更新基址寄存器的值(将最终地址写回<Rn>
)。<寄存器列表>
:用大括号{}
包含的寄存器集合(如r0-r3, lr
),表示需要存储的寄存器。
4.ldmfd
STMFD
通常与 LDMFD(批量加载指令)配对使用:
STMFD sp!, {reg_list}
:压栈(保存寄存器)LDMFD sp!, {reg_list}
:出栈(恢复寄存器)
这种配对确保了栈操作的对称性,是 ARM 汇编中函数调用、异常处理的标准模式。
STMFD sp!, {r4-r7, lr} ; 保存非volatile寄存器和返回地址; 函数体操作...LDMFD sp!, {r4-r7, pc} ; 恢复寄存器并返回(用pc代替lr实现跳转)
可用在函数调用或者中断处理