nop:空转一个机器周期,不准优化;
高位 地位
0x40001000不是一个立即数、
函数传参
1、四个以内的参数R0~R3
2、超过四个的参数使用栈传递
返回值:
返回值存放在R0中.
汇编和从c相互调用:
异常处理
软中断的指令:
示例代码
preserve8 area reset, code, readonly code32 entry b start ; reset nop ; undef b deal_swi ; swi nop ; pre abort nop ; data abort nop ; reserved nop ; irq nop ; fiq deal_swi stmfd sp!, {r4-r12, lr} ;保护现场 sub r0, lr, #0x4 ldr r1, [r0] bic r0, r1, #(0xff << 24) import c_deal_swi bl c_deal_swi ldmfd sp!, {r4-r12, pc}^ ;带模式切换的恢复现场 start ; 立即数 ; 一个数字(或按位取反后)将其循环右移偶数位后所有的1能放进低8位中 ldr sp, =0x40001000 ; 0x4000 0C00 ~ 0x4000 1000 mrs r0, cpsr bic r0, r0, #0x1f orr r0, r0, #0x10 msr cpsr_c, r0 ; 切换工作模式到user ldr sp, =0x40000c00 ; 0x4000 0000 ~ 0x4000 0C00 ;swi #0x2 import main bl main nop b start export asm_add asm_add stmfd sp!, {r4-r12, lr} ;保护现场 add r0, r0, r1 ldmfd sp!, {r4-r12, pc} ;恢复现场 end
这段代码是一个基于ARM架构的启动和中断处理示例,使用了ARM汇编语言编写。它主要展示了如何设置堆栈指针、切换处理器模式、处理软件中断(SWI)以及调用C语言函数。下面是对这段代码的详细解释:
初始化和中断向量表
preserve8
和area reset, code, readonly
是Keil MDK或类似ARM汇编器中的指令,用于设置代码段的属性和名称。code32
指示接下来的代码为32位代码。entry
标记了程序的入口点。- 接下来的几条
b
指令和nop
(无操作)指令构成了中断向量表,分别对应复位(reset)、未定义指令(undef)、软件中断(swi)、预取指令中止(pre abort)、数据中止(data abort)、保留、IRQ(普通中断)和FIQ(快速中断)。这里除了软件中断外,其他中断都简单地通过nop
处理。软件中断处理(
deal_swi
)
- 当软件中断发生时,程序跳转到
deal_swi
。- 使用
stmfd
指令保存当前上下文(寄存器r4-r12和lr)。- 通过
lr
(链接寄存器,存储了中断发生前的返回地址)和ldr
指令获取SWI号。- 使用
bic
指令清除SWI号的高24位(通常用于传递额外的信息或状态)。- 调用C语言函数
c_deal_swi
处理SWI。- 使用
ldmfd
指令恢复上下文并返回。程序启动(
start
)
- 设置堆栈指针
sp
到一个合适的内存地址(这里假设是0x40001000
,但随后又修改为0x40000c00
,这可能是为了用户模式)。- 使用
mrs
、bic
、orr
和msr
指令将处理器模式切换到用户模式(#0x10
是用户模式的模式码)。- 调用C语言函数
main
作为程序的主体。- 使用
b start
指令创建一个无限循环,这在实际应用中可能不是必需的,除非有特定的需求(如重启)。额外的函数(
asm_add
)
asm_add
是一个简单的汇编函数,用于演示如何在汇编中调用并返回。- 它首先保存上下文,然后执行
add
指令将r0
和r1
相加的结果存回r0
,最后恢复上下文并返回。
extern int asm_add(int x, int y); void c_deal_swi(unsigned int num) { switch (num) { case 1:break; case 2:break; case 3:break; default: break; } } int main(void) { return 0;
c_deal_swi
函数:
- 一个C语言编写的函数,用于处理软件中断。这里只是一个框架,根据中断号
num
的不同,可以添加不同的处理逻辑。当前代码中没有实现具体的处理逻辑。main
函数:
- 程序的入口点。这里只是简单地返回一个0值,表示程序正常结束。
extern int asm_add(int x, int y);
:
- 声明了一个外部汇编函数
asm_add
,可以在C代码中调用。尽管在这个示例中没有直接使用这个函数,但它展示了如何声明和使用汇编编写的函数