当前位置: 首页 > news >正文

ARM基础概念 异常处理01 day52

四:ARM汇编语言程序格式

ARM汇编语言是以段(section)为单位来组织源文件的。段是相对独立的、具有特定名称的、不可分割的指令或者数据序列。

段又可以分为代码段和数据段,代码段存放执行代码,数据段存放代码运行时的数据,A搜素解释快速润色总一个ARM源程序至少需要一个代码段,大的程序可以包含多个代码段和数据段。

在汇编文件中,我们需要先定义一个段,在段中添加我们实现的汇编程序语句

一:六大指令集

1.分别为数据处理指令 //(完成CPU内部的计算)

2.Load/Store指令 //(完成CPU与内存IO外设之间的数据传输)

3.跳转指令 //(完成程序的跳转)

4.程序状态寄存器处理指令 //(完成 CPSR的管理)

5.协处理器指令 //(完成CPU扩展功能的实现)

6.异常产生指令 //(用户程序异常触发)

二:指令格式中符号说明

〈opcode〉{〈cond〉}{S}  〈Rd〉,〈Rn〉{,〈operand2〉} 
opcode 			//操作码;指令助记符,如LDR、STR等。         
cond       		//可选的条件码;执行条件,如EQ(相同)、NE(uneq 不相等)等。
S       		//可选后缀;若指定“S”,//则根据指令执行结果更新CPSR中的条件码。
Rd				//目标寄存器。
Rn       		//存放第1操作数的寄存器。
Operand2      	//第2个操作数

三:数据处理指令

算术指令:		  ADD ADC SUB SBC RSB(反向减,就是2 - 1 => 1 - 2) RSC
位 运 算 指令:	 AND(&) ORR(|) EOR(异或) BIC(位清零)
比较指令:		  CMP 	CMN	 	TST 	TEQ
数据搬移:		  MOV 	MVN(按位取反放进去)语法:<操作> 	{<cond>} 	{S} 	Rd, 	Rn, 		Operand2
有比较指令影响标志位 -不指定Rd
数据搬移(MOV指令)不指定Rn
	area reset, code, readonlycode32entrymov r0,#1  		;1搬移到r0中	  #   不超过256mov r1,#2  		;2搬移到r1中add r2, r1, r0sub r3, r1, r0rsb	r4, r0, r1and r5, r0, #0xfforr r6, r1, #0x01eor r7, r0, #0xfebic r8, r7, #0xfemvn r9,#0x01adc r10, r1, r0, LSL#1;sbc r11, r1, r1, LSL#1;rsc r12, r1, r0, LSL#1end
3.1进位的问题
;进位adc的使用area reset, code, readonlycode32entry;0x1 ffff ffff;0x2 ffff ffffmov r0, #0x01 mov r1, #0xffffffff mov r2, #0x02 mov r3, #0xffffffff 	adds r5, r1, r3		;产生进位;产生进位需要+sadc r4, r0, r2		;使用进位end
3.4比较的问题

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

;比较的使用有进位问题,也不需要+scmp r0, r1	;只能两两比较movgt r2,r0	 ;大于moveq 		;等于movgt		;小于;所有指令都将可以 + eq 等。。。可选的条件码;执行为真才能执行  本质上先运算(真?/假?),在放入;图很重要,是判断标志位的启示,可以视为if判断的真假之说
;if判断
mov r0 #4
mov rl #5
mov r2 #3
cmp r0 rl	;先判断r0,r1
cmpgt r0 r2		;上句成立,接着比较  
;为什么用gt,因为涉及到截断特性,不加gt,就随便放入,随便执行了
movgt r3 r0
;1 ~ 100 相加area reset, code, readonlycode32entrymov r0, #1mov r1, #0
loopadd r1, r1, r0add r0, r0 ,#1cmp r0, #101bne loop		;这里用blt还是其他都合理,还是要看标志位end
3.5立即数

一个数(或按位取反)循环右移2^n(移动偶次)位后中所有的1能放进低8位中 范围0~255

;放非立即数或超过范围
ldr sp, =0x40001000    ;将一个地址加载到寄存器中
mov r0, #1		;将立即数1搬移到r0中, #代表立即数
3.6入栈操作指令
ldr sp, =0x40001000   ;栈顶
;Load/Store指令    入栈只是其中之一
;(完成CPU与内存 IO外设之间的数据传输)
STMFD (Push)	块存储- Full Descending stack [STMDB]
LDMFD (Pop)		块装载-Full Descending stack [LDMIA]
------------------------------------------------
;用法
STMFD sp!,{r4-r7,lr}	;表示为r4 ~ r7  再加上一个lr
LDMFD sp!,{r4-r7,pc}	;入栈出栈的顺序要对  先进后出
3.7函数应用(栈)
ldr sp, =0x40001000   ;栈顶
;例子 
funstmfd sp!,{lr}:;保护现场;代码。。。。。。。ldmfd sp!,{lr}	;恢复现场
3.8声明外部函数.c
preserve8	;当c和汇编语言需要对齐8字节,放在最上面,是关键字;函数调用规则
;前四个参数,使用r0,r1,r2,r3存放参数,剩余参数使用栈传递
;返回值存放在r0中;
ldr sp, =0x40001000   ;栈顶
mov r0, #1 
mov r1, #1
mov r2, #1
mov r3, #1
mov r4, #1
mov r5, #1
stmfd sp!, {r4,r5}	;用站import c_add	;声明一个外部符号,给汇编文件使用
bl c_add		;汇编语言不能带参数,不像c

int asm_add(int x,int y);	//c中调汇编,声明int c_add(int a,int b)
{int sum = asm_add(a,b);return sum;
}
export asm_add   ;声明一个内部符号给外部文件使用
ldr sp, =0x40001000   ;栈顶ams_addstmfd sp!,{r4 - r12,lr}		;保险,防止数据篡改add r0,r0,r1ldmfd sp!,{r4 - r12,pc}
3.9出栈代码简化问题
ldmfd sp!, {pc} 
{lr} → 出栈到 LR,相当于“把栈顶值存到返回地址寄存器”,并不直接跳转。{pc} → 出栈到 PC,相当于“出栈并跳转到该地址”,这常用于函数返回。
3.10更改工作状态
mrs r0 cpsr
bic r0 r0 #0xlf
orr r0 r0 #0x10
msr cpsr_c r0
3.11软中断
swi #5		;软中断指令    进入svc模式
;pc会默认跳到8 
3.12总测试
int asm_add(int x,int y);//c中调汇编,声明int c_add(int a,int b)
{int sum = asm_add(a,b);return sum;
}
	preserve8area reset, code, readonlycode32entryldr sp, =0x40001000   ;初始化svc模式的栈;进入C程序,里面也涉及到栈的使用mrs r0, cpsrbic r0, r0, #0x1forr r0, r0, #0x10msr cpsr_c, r0ldr sp, =0x4000c000		;初始化user模式的栈import c_addbl c_addexport asm_add   ;声明一个内部符号给外部文件使用asm_addstmfd sp!,{r4-r12,lr}		;保险,防止数据篡改mov r0, #1mov r1, #1add r0,r0,r1ldmfd sp!,{r4-r12,pc}end

五:异常处理

ARM 有两级外部中断 FIQ,IRQ.

可是大多数的基于ARM 的系统有有>2个的中断源,因此需要一个中断控制器

ps:通常中断处理程序总是应该包含清除中断源的代码

为什么:外设或事件(比如定时器溢出、GPIO 变化、串口接收)会设置一个中断挂起标志位(pending flag)。CPU 检测到这个标志后,进入中断服务程序(ISR)。如果这个标志位不被清除,那么:ISR 执行结束时,CPU 发现中断源还在挂起 → 马上再次进入 ISR。程序就可能死在中断里,永远不回到主程序。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中保存返回地址到LR ,软中断pc会默认跳到8

看图的右边偏移量对应就是每种异常pc默认回到的地址

一:异常规范函数

	preserve8area reset, code, readonlycode32entry
;这里就是异常向量表   预设b start   	; resetnop       	; undefb deal_swi	; swinop			; prefetch abortnop			; data abortnop			; reservednop			; irqnop			; fiqdeal_swi	;预设stmfd sp!, {r4-r12, lr}	  add r0, r0, r1ldmfd sp!, {r4-r12, pc}   startldr sp, =0x40001000	  mrs r0, cpsrbic r0, r0, #0x1forr r0, r0, #0x10msr cpsr_c, r0	   ldr sp, =0x40000C00	   swi #5	 ;ÈíÖжÏÖ¸Áîmov r0, #1mov r1, #2import c_add	bl c_add	 nop     b startexport asm_add	   
asm_addstmfd sp!, {r4-r12, lr}	  add r0, r0, r1ldmfd sp!, {r4-r12, pc}  end	
http://www.dtcms.com/a/327814.html

相关文章:

  • 前端项目一键换肤
  • Web 服务详解:HTTP 与 HTTPS 配置
  • SuperMap GIS基础产品FAQ集锦(20250804)
  • Java 中 Set 接口详解:知识点与注意事项
  • LangChain SQLChatMessageHistory:SQL数据库存储聊天历史详解
  • Day05 店铺营业状态设置 Redis
  • MQTTX使用wss的连接报错
  • Java -- List接口方法--遍历--ArrayList的注意事项
  • 贪心----4.划分字母区间
  • 方格网法土方计算不规则堆体
  • [ 前端JavaScript的事件流机制 ] - 捕获、冒泡及委托
  • 少数民族文字OCR识别技术实现及应用场景剖析
  • JMeter并发测试与多进程测试
  • __base__属性
  • ETCD的简介和使用
  • 42.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--集成网关--网关集成认证(一)
  • 1513-map 的三种声明定义方式 使用方式
  • BN层:深度学习中的“数据稳定器”,如何解决训练难题?
  • 基于C#的二手服装交易网站的设计与实现/基于asp.net的二手交易系统的设计与实现/基于.net的闲置物品交易系统的设计与实现
  • 嵌入式Linux学习 -- 软件编程3
  • UNet改进(32):结合CNN局部建模与Transformer全局感知
  • Docker 101:面向初学者的综合教程
  • 【C#】从 Queue 到 ConcurrentQueue:一次对象池改造的实战心得
  • 激活函数篇(2):SwiGLU | GLU | Swish | ReLU | Sigmoid
  • 如何查看当前Redis的密码、如何修改密码、如何快速启动以及重启Redis (Windows)
  • 鹧鸪云:光伏施工流程管理的智能“导航仪”
  • 云平台监控-云原生环境Prometheus企业级监控实战
  • 【Redis与缓存预热:如何通过预加载减少数据库压力】
  • RoboNeo美图AI助手
  • 如何单独修改 npm 版本(不改变 Node.js 版本)