一段ASM代码

;/*******************************************************************************
; * bla.bla.bla
; ******************************************************************************/

        //开始,列出了ARM处理器各种工作模式

        .set Mode_USR, 0x10     // 用户模式
        .set Mode_FIQ, 0x11     // 快速中断模式
        .set Mode_IRQ, 0x12     // 中断模式
        .set Mode_SVC, 0x13     // 管理模式
        .set Mode_ABT, 0x17     // 中止模式
        .set Mode_UND, 0x1B     // 未定义模式
        .set Mode_SYS, 0x1F     // 系统模式

        .set I_Bit, 0x80        //中断位, 这两位操作可以用来禁止或允许中断
        .set F_Bit, 0x40        //快速中断位

;/*****************************************************************************/

        .text
        .code 32

        .global _start          //程序开始处,从这里开始运行

_start:
        //接着是各种异常处理子程序,ARM有以下几种类型异常处理
        //b 是跳转指令,这里跳转到reset处理子程序  

        b Reset_Handler //复位异常,处理器复位时,产生复位异常,程序跳转到复位异常处理处执行 
        b Undefined_Handler //未定义指令异常,当ARM处理器遇到不能处理指令时,产生未定义指令异常
        b SWI_Handler //软件中断异常,由SWI指令产生
        b Prefetch_Handler //指令预取异常,处理器预取指令不存在,或预取地址不允许当前指令访问,就会发生该异常
        b Abort_Handler //数据中止异常,处理器指令访问数据的地址不存在,产生数据中止异常
        nop
        b IRQ_Handler //外部中断请求,CPSR 的I位为0, 才能产生IRQ异常
        b FIQ_Handler //快速中断请求,CPSR 的F位为0,才能产生FIQ异常
	.string "Copyright (c) STMicroelectronics. All Rights Reserved."     //描述性字符串
	.align 4                                                             //4字节对齐

;/*****************************************************************************/

Reset_Handler:                                    //复位处理子程序                  
	mrc		p15, 0, r1, c1, c0, 0	; /* Get coprocessor special register */  //把协处理器p15的寄存器C0,C1中数据传入 ARM寄存器R1。
	bic		r1, r1, #0x1			; /* MMU disable */             //清除R1的0x1位
	orr		r1, r1, #(0x1 << 12)	; /* Icache enable */             //R1的0x1<<12 位设置1,其它位不变,结果放入R1
	orr		r1, r1, #(0x1 << 2)		; /* Dcache enable */
	bic		r1, r1, #(0x1 << 3)		; /* Write buffer disable */    //R1的0x1<<3位清0
	mcr		p15, 0, r1, c1, c0, 0	; /* Store processor special register */  //把R1的数据传回给协处理器P15的C0,C1寄存器

	; /* Fill stack with pattern */
	ldr		r1,=__SP_START         //将__SP_START加载到R1, __SP_START --- 栈STACK的起始地址
	ldr		r2,=__SP_END           //将__SP_END加载到R2,  __SP_END --- 栈STACK的结束地址
	ldr		r3,StackFill           //将StackFill加载到R3,StackFill = 0xAAAAAAAA, 下面有定义
1:
	cmp		r1,r2     //比较R1和R2
	stmltia	r1!,{r3}          //lt 表示前面比较r1 < r2 时,也就是__SP_START < __SP_END时,将R3的值保存到R1所指向的存储单元中,R1自动加1
	blt		1b        //r1 < r2时,跳转到前面的cmp,继续比较r1和r2, 因为R1不断+1,所以栈的每个位都会被初始化为StackFill

	; /* Check to see if the backup RAM has our magic key. */
	ldr		r2, BackupRAM         //将BackupRRAM 载入R2
	ldr		r1, MagicKey          //将MagicKey 载入R1
	ldr		r0, [r2]              //将BackupRAM地址中的数据载入R0
	cmp		r0, r1                //比较R0和R1
	beq		InitStacks            //如果相等则跳转到InitStacks
	str		r1, [r2]              //将R1中的值写入到R2寄存器值所指的存储器地址上,也就是BackupRAM所指的地址上

	; /* Clear uninitialized data segment */
	ldr		r1,=__BSS_START       //BSS起始地址
	ldr		r2,=__BSS_END         //BSS末尾地址
	mov		r3,#0                 //这R3用来实现清0 BSS区
1:
	cmp		r1,r2             //比较R1,R2 
	stmltia	r1!,{r3}                  //如果R1<R2, 则把R3中的值写入R1值所指的存储单元, R1中的值+1
	blt		1b                //如果R1<R2, 跳转到前面最近的1处

;/***************************************************************************/

InitStacks:
	msr		CPSR_c, #(Mode_IRQ | I_Bit | F_Bit)      //将 0x12 | 0x80 | 0x40 = 0xD2 写入CPSR_c,CPSR_c 是指CPSR的控制域部分
	ldr		sp,=__IRQ_STACK_INIT                     //跳入__IRQ_STACK_INIT

	msr		CPSR_c, #(Mode_FIQ | I_Bit | F_Bit)
	ldr		sp,=__FIQ_STACK_INIT

	msr		CPSR_c, #(Mode_SVC | I_Bit | F_Bit)
	ldr		sp,=__SVC_STACK_INIT

	msr		CPSR_c, #(Mode_ABT | I_Bit | F_Bit)
	ldr		sp,=__ABT_STACK_INIT

	msr		CPSR_c, #(Mode_UND| I_Bit | F_Bit)
	ldr		sp,=__UND_STACK_INIT

	msr		CPSR_c,#(Mode_SYS | I_Bit | F_Bit)
	ldr		sp,=__SP_END

	.extern main     //调用外部函数

	b		main

	swi		0xFFFFFF       //产生软中断指令,

Undefined_Handler:
	mov		r0,#'U'        //字符U送入R0
	b		uart_out       //跳转到UART 打印输出子程序
SWI_Handler:
	mov		pc, lr         //跳转到链接寄存器,当之前执行BL调用时,LR得到PC的备份。
Prefetch_Handler:
	mov		r0,#'P'
	b		uart_out
Abort_Handler:
	mov		r0,#'A'
	b		uart_out
IRQ_Handler:
	mov		r0,#'I'
	b		uart_out
FIQ_Handler:
	mov		r0,#'F'
	b		uart_out

uart_out:
	ldr		r1,uart      //uart 值是0x101FB000, 是UART1的数据寄存器地址,数据送到这个地址,就会打印到串口输出上
1:
	str		r0,[r1]      //把R0的值,发送到R1的值所指的存储单元上,也就是0x101FB000 = R0.
	b		1b

	.global	MagicKey             //全局变量

BackupRAM:	.word	0x80010000
MagicKey:	.word	0x5aa555aa
StackFill:	.word	0xAAAAAAAA
uart:		.word	0x101FB000

	.size   _start, . - _start
	.end



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值