汇编 C混调 异常处理
来源:互联网 发布:指尖软件 编辑:程序博客网 时间:2024/05/21 17:20
汇编程序与C程序混合调用
- 在C语言中如何调用汇编语言实现的函数
- 在C语言中如何使用汇编语言定义的变量
- 汇编语言中如何调用C语言的函数
汇编语言中如何调用C语言定义的变量
在C语言中如何调用汇编语言实现的函数
例如用汇编比较两个字符串是否相等的函数的代码片段:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
C语言调用函数的过程的代码片段:
main.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
遵循的原则:
- 汇编函数的名字声明为全局标号 “.global my_strcmp”
- C程序中如要调用这个汇编函数,需要声明该函数的函数原型
- 1
- 1
- 按照C语言的方式去调用该函数
C语言中如何使用汇编语言定义的变量
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
1,在汇编中将变量声明为全局变量
2,在C语言中声明该变量为外部变量
- 1
- 1
3,按照C的方式去使用该变量
汇编语言中如何调用C语言的函数
- 1
- 2
- 3
- 1
- 2
- 3
1,在C程序中该函数要定义为全局,即函数前面不能加static
2,汇编程序中将该函数声明为外部标号
- 1
- 1
3,按照汇编的方式调用
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
关键是:参数的传递规则
int add(int a,int b,int c,int d)
r0, r1 r2 r3
汇编语言中如何调用C语言定义的变量
int a ;
1,C中声明为全局变量
2,汇编程序中声明该变量为外部变量
- 1
- 1
3,按照汇编的方式使用
- 1
- 2
- 3
- 1
- 2
- 3
总结:
被调用方循环的原则:
将被调用的函数或变量都要定义为全局
调用方:
声明被调用函数的函数原型或者变量为外部标号
参数传递:
r0,r1,r2,r3
r0作为返回值
案例:
在C程序中调用汇编实现的函数
将用汇编实现的字符串比较函数替换掉用C实现的字符串比较函数
1,汇编函数(字符串比较函数)定义为全局标号
2,在C程序中将该汇编函数声明函数原型
3,替换掉C的字符吕比较函数,用汇编函数
astrcmp.s
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
.h声明函数原型
- 1
- 2
- 3
- 1
- 2
- 3
修改makefile
在C中调用
start.s
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
异常处理
1,复位异常,进入管理SVC模式
2,未定义指令异常,不能识别指令,进入未定义模式
3,软中断异常,指行swi指令,进入SVC模式
4,预取指令异常,没有取到指定的指令,进入中止模式
5,数据中止异常,没有取到指定的数据,进入中止模式
6,中断,进入中断模式
7,快速中断,进入快速中断模式
工作模式:
异常模式
管理
快速中断
中断
中止
非异常模式
当发生异常时,如保处理?
CPU做:
1,拷贝CPSR到相应异常模式的CPSR,SPSR_mode = CPSR (备份)
2,设置适当的CPSR的位:
1. 将处理器的状态改为ARM状态,CPSR的bit[5] = 0
2. 改变处理器的工作模式,进入到对应的异常工作模式,改CPSR的bit[4:0]到对应的异常模式
3. 设置中断禁止位,
3,保存返回地址到LR_mode = PC -4(PC -2),异常返回的问题
4,设置PC为相应异常处理程序的入口(异常向量表)
5,处理异常,执行异常处理
6,异常返回,CPSR = SPSR_mode (MOVS PC ,LR)
异常向量表:
软中断
系统执行代码,执行到SWI 0x01指令,在该指令的执行阶段,发生软件中断异常
CPU:
1,备份CSPR,SPSR_SVC = CPSR
2,修改CPSR
1.改状态,ARM状态,CPSR的bit[i]=0
2,改模式,SVC管理模式,CPSR的bit[4:0] = 10011
3. 改中断禁止位
3,保存返加地趣为LR_SVC
4,修改PC为异常向量表中对应的入口地址,PC = 0x8
对应指令:ldr pc,swi_hdl
再次修改PC = swi_hdl函数地址
5,swi_hdl,软中断异常处理程序 ,在此程序中调用C语言缩写的较为复杂的处理程序 (汇编调用C函数的混合调用)
6,当C函数处理异常完毕之后,返回汇编swi_hdl,再做最后的异常返回.
7,movs pc,ls CPSR = SPSR_SVC
8,接下来继续执行swi指令的下一条指令
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
reset.s
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
reset.s
1,将模式改为SVC管理模式,并且屏蔽中断,初始化栈顶指针SP
2,安装MMU的地址转换表,之后CPU给的地址都是虚拟地址
3,初始化IRQ和FIQ模式下栈顶指针
4,清空BSS段
5,跳转到main执行主函数(shell,汇编调用C的混合调用)
提取swi指令中中断号:
swi指令格式:
1,在ARM状态下,执行ARM指令,SWI指令,低24bit为中断号
2,在thumb状态下,执行thumb指令,swi指令,低8bit为中断号
ARM指令格式(32bit):
Thumb指令格式:
1,确定执行swi指令时,CPU所片的状态,ARM? thumb?
由于发生异常时,SPSR_SVC = CPSR
判断SPSR的bit[5] = 0,ARM状态,swi指令是指令(32)
bit[5] = 1,thumb状态,swi指令是thumb指令(16)
1,读SPSR寄存器到R0,MRS指令
2,用位运算bit[5] ANDS EQ(ARM) NE(thumb)
2,获取swi指令的编码
由于发生异常时,保存返回地址 lr = pc -4 ARM
= pc - 2 thumb
ARM 状态: swi指令码的地址,lr - 4
Thumb状态,swi指令码的地址,lr-2
ldreq 加载ARM指令 r0,[lr-4] ldrneh 加载thumb指令 r0,[lr - 2]
3,使用位运算获取到swi指令码中中断号,将中断号存在R0
ARM指令:提取低24bit
Thumb:提取低8bit
通过位运算,中断号保存在r0
1,biceq r0 24bit , 清除24bit
2,andne r0 8bit,
4,R0中断号做为参数,传递给C函数
5,进入c_swi_handler(unsigned int num),伪代码如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
取指,解码,执行,在swit指令的第三个阶段,执行阶段,发生异常
1,SPSR= CPSR
2,改CSPR ,ARM状态,SVC模式,中断禁止位
3,保存返回地址 LR= PC -4 add指令地址
= PC -2
- 汇编 C混调 异常处理
- arm第十一天(汇编与C混调、异常处理)
- c#中的异常处理
- 异常处理 - [C++]
- c异常处理
- Objective-c异常处理
- C语言异常处理
- c 异常处理
- C 异常处理设计
- [C++] 异常处理
- C++“异常处理”
- objective-c 异常处理
- 【C++】栈空栈满异常处理
- C++:异常处理
- c++_10: 异常处理
- 【C#】异常处理
- C/C++异常处理
- C++‘异常’处理机制
- sql server身份证校验
- Android中keystore文件的SHA1获取方法
- 关于Android7.0相机闪退以及相册获取不到图片问题
- JSP cookie基础
- 构造函数加上void就不是构造函数了
- 汇编 C混调 异常处理
- 【DP】洛谷 P1470 最长前缀 Longest Prefix
- Hadoop安装教程_单机/伪分布式配置_CentOS6.4/Hadoop2.6.0
- redis扩展
- JDBC-创建数据库
- if语句解析
- JavaScript中的call,apply,bind
- //layui的模板引擎和分页组合用
- 后台任务稳定运行方案--不受终端关闭或者远程(ssh等)连接失败影响