ARM汇编语言和C_C_语言混合编程的方法_史斌

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2 ATPCS 规则(ARM-Thumb Produce Call Standard)
A TPCS 体现了一种模块化设计的思想 , 其基本内容
是 C /C ++模块(代码段)和汇编模块(函数)相互调用的 一套规则(很多 C /C ++编译器都有类似的规则), 其具体 内容为(不涉及 A RM 代码和 Thum b 代码的相互调用)。 2. 1 被调用模块的寄存器使用
C /C ++主程序 : #define UIN T un signed int extern UINT add _ six (UINT a , UIN T b , UINT c , UIN T d , UINT e , UIN T f); / /声明 add_ six 不是在本模块定义的 int m ain(void) { add(1 , 2 ,3 , 4 , 5 ,6); ret urn 0 ; } 汇编子程序 : area cdo , code , readonly ; 段名 cdo , 代码段 code32 ; A RM 指令 add_six ; 标号 global add_six ; add_six 是全局标号 stmfd r13 , {r4 , r5}; 将 r4 , r5 压入堆栈 ,但 r13 不变 ldr r4 ,[ r13] ; 将第 5 个参数从堆栈中提出 ldr r5 ,[ r13 , #4] ; 将第 6 个参数从堆栈中提出
Abstract:T his article briefly introduced A RM serial micropro ce sso r , w hich is ex tensiv ely used in embedded sy stem desig n;and then g ave the tw o metho ds of A RM-cor e embedded processor prog ramming with both assembly and C /C ++ Language including in-line assembly w hich is co mpact but have so me limits and A T PCS rules w hich are pow erful and mo dularized. A t last , the re is some source code w ith analy sis for demo nstra tion. Keywords:embedded sy stem ;A RM ;assembly ;in-line assembly ;A T PCS
调用模块和被调用模块通过 r0r3 传递参数 , 因此参数 少于 4 个时可以随意使用剩余的寄存器而不必保存和恢 复 ;使用 r4r11 之前一定要先在堆栈中保存起来 , 退出时再 恢复 ;可以使用堆栈 , 但一定要保证堆栈指针(r13)在进入 时和退出时相等 ;r14 用于保存返回地址 , 使用前一定 要 备份 。 2. 2 被调用模块的堆栈使用
Programming of ARM with both assembly and C/C ++ language
Shi Bin (S chool of Elect ronic & Inf ormation Engin eeri ng Tianjin U niversit y , Ti anji n 300072)
{ M RS r0 , CPS R ;/ /将状态积存器的内容传递 到 r0 ORR R0 , R0 , 0x000000C0 ;/ /通过或运算将 r0 的第 6 , 7 两位置 1 , 其它位不变 M SR CPSR_ c , r0 ;/ /将 r0 的 低 8 位送 到 CPS R 的低 8 位 , 以屏蔽 FIQ 中断 } IN TPND =0xfffff fff ;/ /清除 全部中 断标志 位 , C /C ++代码 } 因为 CPS R 是一个物理寄存器 , 没有存储器的 I /O 映 射 , 而 A RM 的 C /C ++语言使用的是 ANSI 标准 , 不 像 KeilC51 那样有诸如 sbit 和 sfr 的扩展 , 所以访问 C PS R 的 唯一方法就是用汇编语言 ;通过在 C /C ++代码中插入一 段简短的汇编代码 , 来实现对 CPSR 的访问 。再比如一些 波形发生的场合 , 需要每隔一段精确 的时间向端口送 数 据 , 那么 C /C ++代码经编译后产生的指令数是无法预知 的 , 所以无法实现精确定时 , 因此就要使用在线汇编 。 在线汇编通过__asm 关键字实现 , 一般格式为 : … … / / C /C ++代码 __asm { 指令 1 ;指令 2 ;指令 3 ;……
A TPCS 规则规定堆栈是满递减(FD-Full Decrease)型 的 , 因此使用 S TM FD /LDM FD 指令操作 , 注意保证进 入 和退出时堆栈指针相等 。 2. 3 参数传递
当参数少于 4 个时 , 按从左到右的顺序依次放在 r0 、 r1 、r2 、r3 中 ;
当参数多于 4 个时 , 前 4 个放在 r0 、r1 、r2 、r3 中 , 剩余 的放在堆栈中 , 最后一个 参数先入栈 , 第 5 个参数最后入 栈 , 即从右到左入栈 。 2. 4 返回值
89
第 29 卷
电 子 测 量 技 术
指令 n ;指令 n +1 ;…… … … } / / 括号内为汇编代码 … … / / C /C ++代码 其中汇编指令的操作数可以是物理寄存器 , 也可以是 C /C ++语言的变量 、行号和表达式 , 这点是比纯汇编代码 最大的方便之处 。 其实写在线汇编代码的思路和纯汇编 差不多 ,但要注意在线汇编的几个限制 : (1)不能直接向程序存储器 PC 赋值实现程序跳转 ,只 能使用 B 和 BL 这两条指令 ; (2)在线汇编器会使用 r0r3 , r12r13 计算表达式 , 因此 复杂的表达式不能和以上寄存 器出现在同一条指 令中 。 比如 : m ov r0 , 一个复杂的表达式 ———汇编器可能报错 m ov r5 , 一个复杂的表达式 ———汇编可以通过 ; (3)在线汇编中使用物理寄存器时 , 如果上下文的 C / C ++生成的代码也使用了同一个 , 则不必在汇编代码中 保存和恢复该物理寄存器 , C /C ++代码会负责处理 ; (4)操作数尽量不使用物理寄存器 , 因为影响代码效 率 , 很有可能编译器为此把一个本应放在寄存器中的变量 放在存储器中 。 就如同在 C /C ++中定义局部变量哪个 是 register 的 , 哪个是 volatile 的 , 编译器自己的优化才是 最佳的 。而且使用物理寄存器常会发生错误 。 比如 : m ov r0 , #0xaa m ov r1 , x %y m ov r2 , r0 很可能 r2 的值不是 0xaa , 因为在计算表达式 x %y 时 会用到 r0 , 将 r0 的内容冲掉 ; (5)可以使用 b 指令 :b 标号 ;实现跳转 , 标号可以是 C /C ++的也可以是汇编的 ; (6)因为要计算表达式的值 , 所以一条虚拟指令要被 展开为若干条真实指令(如上面的 mov r1 , x %y), 因此实 际上对标志为 C. N. V. Z 的影响是展开后最后一条作用的 结果 , 但如果总的虚拟指令是算术指令 , 那么能正确设置 C . N. V. Z , 如果是逻辑指令 , 那么 N . Z 是正确的 , V 不影 响 ,C 不可靠 ; (7)不支持除 NO P 之外的其他伪指令(ADR , ADRL , L DR) ; (8)不支持 BX 和 B LX 指令 ; (9) LDM 和 ST M 指令的寄存器列表只允许物理寄存 器 , 不能用变量和表达式 ; (10)逗号表达式要用一个括号扩起来 , 使其为一个整 体 , 如 add x ,y , (f(), z); (11)不要干预堆栈 。
结果为 32 位时 ,通过 R0 返回 ; 结果为 64 位时 , r0 放低 32 位 , r1 放高 32 位 。
3 ATPCS 规则的示例代码和分析
以下 2 个例子均实现 6 个无符号整数的加法 , 一个是 C /C ++主程序调用汇编子程序 ;另一个是汇编主程序调 用 C /C ++子程序 。2 个程序都在 ADS1. 2 中调试通过 。 3. 1 C /C ++主程序调用汇编子程序
return a +b +c +d +e +f ; } 可以看到 C /C ++子程序实现 add_six 函数的过程比
源自文库90
史 斌 :ARM 汇编语言和 C /C ++语言混合编程的方法
第6期
add r0 , r0 , r1 add r0 , r0 , r2 add r0 , r0 , r3 add r0 , r0 , r4 add r0 , r0 , r5 ; 32 位结果保存在 r0 中 sub r3 , r13 , #8 ldmfd r3 ,{r4 , r5}; 从堆栈中恢复 r4 , r5
m ov r15 , r14 ; 返回主程序 end ; 汇编结束 可以看到 C /C ++主程序比较简洁 , 仅仅是调用外部 函数 add_six ;而汇编文件是函数 add_ six 的实现模块 , 先 从堆栈中取出后 2 个参数放在 r4 、r5 中 , 然后与放在 r0 、 r1 、r2 、r3 中的前 4 个参数相加 ,最后将结果放在 r0 中作为 返回值 。其流程如图 1 所示 。
0 引 言
A RM 是一种高性能 、低功耗的 32 位 RISC 嵌入式处 理器系列 。目前在各种嵌入式系统中 A RM 获得了广泛的 应用 。
A RM 编程可以使用汇编语言和 C /C ++语言 , 使用 汇编语言编程目标代码效率较高 , 但较为繁琐 , 设计大型 系统时不易维护 ;而 C /C ++语言比较简洁明了 , 但代码 效率即使经过优化 , 也比汇编语言低 , 特别是在一些实时 性强和需要精细处理的场合 , C /C ++语言难以胜任 。因 此一个折中的办法是 :使用 C /C ++语言写整体框架 , 而 使用汇编语言实现局部模块 , 这就涉及到汇编语言和 C /C ++语言混合编程的问题 。为此本文介绍了在 ADS 中常 用的 2 种汇编语言和 C /C ++语言混合编程方法 :在线汇 编 (in-line assem bly )和 AT PCS (A RM-T humb Produce C all S tandard)规则 。
1 在线汇编( in-line assembly)
在线汇编的具体含义就是 :在 C /C ++代码中插入一 段汇编代码 ,以实现某种 C /C ++无法达到的效果 , 例如 :
{ INTM SK =0xfffff fff ;/ /屏蔽所 有的 向量中 断 , C /C ++代码 __ asm / /插入一段汇编代码
嵌入式技术
电 子 测 量 技 术 ELECT RO NIC M EA SU REM EN T T ECHN O LO G Y
第 29 卷 第 6 期 2006 年 12 月
ARM 汇编语言和 C/ C ++语言混合编程的方法
史斌
(天津大学电子信息工程学院 天津 300072)
摘 要 :文中首 先对在嵌入式系统设计中广泛应用的 A RM 系列微处理器做了简要介绍 ;接着详 细阐述了基 于 A RM 核的嵌 入式微处理器的汇编语言和 C /C ++语言混合编程的方 法 :包 括代码简洁 而功能有 限的在线汇 编技术 和功能 强大 、基于模块化设计的 A T PCS 规则 ;最后给出了详细的示例代 码和分析 。 关键词 :嵌入式 系统 ;A RM ;汇编语言 ;在线汇编 ;A T PCS 规则
相关文档
最新文档