arm 软中断模拟

程序实现功能:
模拟arm转中断,实现软中断号6 触发累加和运算(数据是 3,4,5,6),运算后的值保存在R8中。

.text	

@异常向量表
b reset @0x00
ldr pc, _undefined_instruction @0x04 不用b,是因为解决b指令上下跳转32M限制,具体看下方注解1
ldr pc, _software_interrupt @0x08 swi
ldr pc, _prefetch_abort @0x0c
ldr pc, _data_abort @0x10
ldr pc, _not_used @0x14
ldr pc, _irq @0x18
ldr pc, _fiq @0x1c

_undefined_instruction:
.long _undefined_instruction
_software_interrupt:
.long software_interrupt
_prefetch_abort:
.long _prefetch_abort
_data_abort:
.long _data_abort
_not_used:
.long _not_used
_irq:
.long _irq
_fiq:
.long _fiq

@软中断处理函数

software_interrupt:
stmfd sp!,{r3,lr} @保护现场
sub r1,lr,#4 @lr-4,取出swi程序的地址,做中断码判断
ldr r1,[r1]
bic r1,#0xff000000 @只取出低24位的机器码,原因看下方注解

bl  swi_num_handler         @跳到中断码判断程序
ldmfd sp!,{r3,pc}^               @恢复现场


@中断码判断程序

swi_num_handler:
cmp r1,#1
moveq r0,#1

cmp   r1,#2
moveq r0,#2

@----------
cmp   r1,#3
moveq r0,#3

cmp   r1,#6                     @swi 中断号为6处理程序
mov   r4,#2                     @r4  赋初值2

sum:
add r4,#1 @r4 作为变量累加
add r8,r4 @把r4中的值累加到r8中
cmp r4,#6 @判断循环是否结束,如果结束跳 转
@ swi_num_handler_end
beq swi_num_handler_end
b sum

swi_num_handler_end:
mov pc,lr @返回

@主程序

reset:
ldr sp,=stack_base @为栈开辟空间
mrs r0,cpsr @切换用户模式
and r0,#0xD0
msr cpsr,r0

swi 0x06                @跳到软中断异常入口
                             @并保存下一条语句的地址到lr中
b reset

@数据段
.data

buf:
.space 20*4
stack_base: @栈开辟空间

.end

注解:arm 软中断模拟_第1张图片
软中断低24位,为中断号的存放位置,所以只取24位做判断;

arm 软中断模拟_第2张图片
为何跳转32M,引用这位博主的见解添加链接描述

你可能感兴趣的:(汇编学习)