ARM汇编语言和C_C_语言混合编程的方法_史斌
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)
1 在线汇编( in-line assembly)
在线汇编的具体含义就是 :在 C /C ++代码中插入一 段汇编代码 ,以实现某种 C /C ++无法达到的效果 , 例如 :
{ INTM SK =0xfffff fff ;/ /屏蔽所 有的 向量中 断 , C /C ++代码 __ asm / /插入一段汇编代码
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 个参数从堆栈中提出
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 返回值
嵌入式技术
电 子 测 量 技 术 ELECT RO NIC M EA SU REM EN T T ECHN O LO G Y
第 29 卷 第 6 期 2006 年 12 月
Hale Waihona Puke ARM 汇编语言和 C/ C ++语言混合编程的方法
史斌
(天津大学电子信息工程学院 天津 300072)
摘 要 :文中首 先对在嵌入式系统设计中广泛应用的 A RM 系列微处理器做了简要介绍 ;接着详 细阐述了基 于 A RM 核的嵌 入式微处理器的汇编语言和 C /C ++语言混合编程的方 法 :包 括代码简洁 而功能有 限的在线汇 编技术 和功能 强大 、基于模块化设计的 A T PCS 规则 ;最后给出了详细的示例代 码和分析 。 关键词 :嵌入式 系统 ;A RM ;汇编语言 ;在线汇编 ;A T PCS 规则
结果为 32 位时 ,通过 R0 返回 ; 结果为 64 位时 , r0 放低 32 位 , r1 放高 32 位 。
3 ATPCS 规则的示例代码和分析
以下 2 个例子均实现 6 个无符号整数的加法 , 一个是 C /C ++主程序调用汇编子程序 ;另一个是汇编主程序调 用 C /C ++子程序 。2 个程序都在 ADS1. 2 中调试通过 。 3. 1 C /C ++主程序调用汇编子程序
2 ATPCS 规则(ARM-Thumb Produce Call Standard)
A TPCS 体现了一种模块化设计的思想 , 其基本内容
是 C /C ++模块(代码段)和汇编模块(函数)相互调用的 一套规则(很多 C /C ++编译器都有类似的规则), 其具体 内容为(不涉及 A RM 代码和 Thum b 代码的相互调用)。 2. 1 被调用模块的寄存器使用
m ov r15 , r14 ; 返回主程序 end ; 汇编结束 可以看到 C /C ++主程序比较简洁 , 仅仅是调用外部 函数 add_six ;而汇编文件是函数 add_ six 的实现模块 , 先 从堆栈中取出后 2 个参数放在 r4 、r5 中 , 然后与放在 r0 、 r1 、r2 、r3 中的前 4 个参数相加 ,最后将结果放在 r0 中作为 返回值 。其流程如图 1 所示 。
调用模块和被调用模块通过 r0r3 传递参数 , 因此参数 少于 4 个时可以随意使用剩余的寄存器而不必保存和恢 复 ;使用 r4r11 之前一定要先在堆栈中保存起来 , 退出时再 恢复 ;可以使用堆栈 , 但一定要保证堆栈指针(r13)在进入 时和退出时相等 ;r14 用于保存返回地址 , 使用前一定 要 备份 。 2. 2 被调用模块的堆栈使用
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)不要干预堆栈 。
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)规则 。
return a +b +c +d +e +f ; } 可以看到 C /C ++子程序实现 add_six 函数的过程比
{ 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 ;……
arm学习笔记五(cc++与arm汇编混合编程)
arm学习笔记五(cc++与arm汇编混合编程)混合编程常见⽅式:1 在c/c++程序中嵌⼊汇编指令语法格式:__asm{汇编语⾔程序}2 在汇编程序中访问c/c++定义的全局变量⽰例代码如下:test.c#include <stdio.h>int gVar_1=12;extern asmDouble(void)int main(void){printf("original value of gVar_1 is %d",gVar_1);admDouble();printf("modified value of gVar_1 is %d",gVar_1);return 0;}test.sAREA asmfile,CODE,READONLYEXPORT asmDouble;声明全局引⽤标号IMPORT gVar_1;引⽤asmDoubleldr r0,=gVar_1ldr r1,[r0]mov r2,#2mul r3,r1,r2str r3,[r0]mov pc,lrEND3 在c/c++程序中调⽤汇编函数⽰例代码如下:test1.sAREA asmfile,COCE,READONLYEXPORT asm_strcpy;声明全局引⽤标号asm_strcpy;函数名loop:ldrb r4,[r0],#1cmp r4,#0beq overstrb r4,[r1],#1b loopover:mov pc,lr;⽤于函数返回ENDtest1.c#include <stdio.h>extern void asm_strcpy(const char *src,char *dest);int main(){const char *s ="hello world";char d[32];asm_strcpy(s,d);printf("source:%s",s);printf("destination: %s",d);return 0;}上⾯程序jni的味道有⽊有?4 汇编程序中调⽤c/c++函数⽰例代码如下:test2.cint cFun(int a,int b,int c){return a+b+c;}test2.sEXPORT asmfileAREA asmfile,CODE,READONLY IMPORT cFun;引⽤函数ENTRY;指定应⽤程序⼊⼝mov r0,#11mov r1,#22mov r2,#33BL cFun;返回END。
ARM9汇编语言与CC++语言的混合编程
ARM9汇编语言与C/C++语言的混合编程ARM体系结构支持ARM的汇编语言与C/C++语言的混合编程。
在一个项目中,至少有一个汇编源文件或C/C++语言文件,可以有多个汇编文件或多个C/C++程序文件,或者C/C++程序文件和汇编文件两者的组合。
一般地,ARM源程序文件名的后缀如表4.2所示。
表4.2 ARM源文件类型及扩展名硅谷芯微嵌入式学院技术贡献官方网址:一般来讲,在设计一个完整的嵌入式程序中,除了初始化部分用汇编语言完成外,其大部分的编程任务一般都用C/C++完成。
当需要C/C++与汇编混合编程时,可以有以下两种处理策略:■若汇编代码较短,则可在C/C++源文件中直接内嵌汇编语言实现混合编程。
■若汇编代码较长,可以单独写成汇编文件,最后以汇编文件的形式加入项目中,通过ATPCS规定与C程序相互调用及访问。
ATPCS,即ARM/Thumb过程调用标准(ARM/Thumb Procedure Call Standard),它规定了一些子程序间调用的基本规则,如子程序调用过程中的寄存器的使用规则、堆栈的使用规则、参数的传递规则等。
本节讨论混合编程的相关技术,将其分为以下3个方面:■内嵌汇编语言指令。
■汇编与C/C++程序的变量相互访问。
■汇编与C/C++程序的函数相互调用。
•4.3.1 内嵌汇编语言指令用C/C++程序嵌入汇编程序中可以实现一些高级语言没有的功能,提高程序执行效率。
Armcc编译器的内嵌汇编器支持ARM指令集,tcc编译器的内嵌汇编器支持Thumb指令集。
•4.3.1.1 内嵌汇编指令的语法格式在ARM的C语言程序中可以使用关键字__asm来加入一段汇编语言的程序,格式如下:__asm{指令[;指令] /*注释*/ ...[指令]}其中,{}中的指令都为汇编指令,一行允许写多条汇编指令语句,指令语句之间要用分号隔开。
在汇编指令段中,注释语句采用C语言的注释格式。
ARM C++程序中除了可以使用关键字__asm来标识一段内嵌汇编指令程序外,还可以使用关键词asm来表示一段内嵌汇编指令,格式如下:asm ("指令"); /*注释*/其中,asm后面的括号中必须是一条汇编指令语句,并且不能包含注释语句。
ARM汇编语言与C/C++语言混合编程实现方法
1 . 1 寄存 器使用规则
A T F CS为 AR M 寄 存 器 进 行 不 同命 名,
任务的效率很高 ,但是 工作量 却非常大,会影
响到对于应用程序 的维护 。若 是所有 的程 序都 是 由 C/ C + +语 言进 行编 程 ,虽然执 行 过程 比
从 而在编程 的过 程 中来 利用 A T P CS寄存器进
是由 C / C + +语 言来 完成 ,从而 达 到 了最 大 的 效果 。
1 A T P C S 调用标准
A RM 处 理器 主 要 是利 用 编 译器 将 汇编 语 言 以及 C / C+ +语 言进 行相 互 的切换 ,并且
进行参数的传递,若参数的数量多余四个 ,那
么必须要利用堆栈来进行参数的传递,所 以参 数之 间传递 的规则不同。
2 0 0 9 . 5 ( 1 1 ) : 2 8 9 6 -2 8 9 7 .
连 接 摄 像 头输 入 到 P l ,连 接 视 频 信 号输 出 步,实时 、高压缩 比的压缩技术是存储和传 J 7 到 显 示器 A V输 入 ,串 口终 端切 换 到 / o p t / 输 的基 础 。本系 统 选择 MP E G一 4这 一视 频压 缩标准 ,其具有 高压缩 比、动态特性好 、存储 S D c a r d t e s t d i r 目录 下刷 新可 以看 到录制的 文件 容量优势 明显等 特点。车载视频监控系统涉及 t e s t . mp e g 4 。接 下来运行 解码程序 d e c o d e 解 码 多个摄像头 ,位 于客 车的不同位置 ,由于安全
d v s d k目录 。运 行 编 码 程 序 e n c o d e 。在 / mn t / t e s t . mp e g 4 ,稍 等即可 看到 显示器 有解 码 的图 像输出。测试操作完成后卸载 S D卡文 件系统。 如图所示主程序测试流程 。如 图 5所示 ,主程 序 完成 系 统 的加 载,包 括 B o o t L o a d e r的启动 和加载,硬件驱动程序 、操作 系统 的加载 和启
ARM汇编语言与C/C++语言混合编程实现方法
摘
要
嵌入 式应用程序开发 中通常采用 A M 汇编语 言与 c C + R / + 语言混合编程, 本文针对 A M 汇 R
编语言与 C C + / + 语言混合编程 实现方法: 内嵌汇编和 A P S规则进行讨论 、总结 ,并通过 实例说明 。 TC
关键词 A M 汇 编语 言 R CC 语 言 混合 编 程 ,抖
1 2 堆 栈 的使用 规 则 .
参 数使 用堆栈 传递 ,所 以要想 参数 传递 简单 ,最 好 函数 的参数 个数 小于 等于 4 。
AP T CS 规 定 堆 栈 采 用 满 递 减 类 型(DF l F ,ul
D s n i )即堆栈通过减小存储器地址而向下 ec d g, e n
在 嵌 入 式应用 程 序 的设计 中 , 果所 有 的编 如 程 任 务都 由汇 编语 言 来完成 , 然 目标 代码 执行 虽
1 A P T CS 过 程 调 用 标 准 ( ARM/ u Th mb
P o e u e lSa d r ) r cd r l tn a d Ca
2 汇编程序调用 C + . 4 + 程序
实例 1用 汇编语 言 调用 C语 言方 法实现 字 符 串 的复制 。 / 语 言 / C
v i sca ’ hr ) od (h r a c a {
fr !. ’ o( a= 0; ; \ )
Sit) i ) ) ( :( { ns s
it ; n i
} ;
玎 始化 该 结构对 象 / 调用 C程序
b b 4) =+ ;
)
b a;
/ C + 序调 用 的 C程 序 / +程 被
sut t c r S{
第四讲ARM汇编语言与嵌入式C混合编程
TM
22 22
内嵌汇编器与armasm汇编器的区别
内嵌汇编器不支持“LDR Rn, = expression”伪指令,使用“MOV Rn, expression”代替,不支持ADR、ADRL伪 指令
TM
9
9
如果系统包含浮点运算的硬件部件,将按照 如下规则传递:
各个浮点参数按顺序处理 为每个浮点参数分配寄存器。分配方法是:找到
编号最小的满足该浮点参数需要的一组连续的FP 寄存器进行参数传递。
TM
10 10
子程序结果返回规则
(1)结果为一个32位的整数时,通过寄存器R0返回;结果 为一个64位整数时,通过寄存器R0,R1返回。
在ARM开发工具编译环境下,汇编程序中要使用 EXPORT伪操作声明本程序可以被其他程序调用。 同时也要在C程序中要用关键字extern声明要调用的 汇编语言程序。
TM
34 34
示例解析
(1)在GNU ARM编译环境下设计程序,用 用C语言调用ARM汇编语言C语言实现20的 阶乘(20!)操作,并将64位结果保存到 0xFFFFFFF0开始的内存地址单元,按照小 端格式低位数据存放在低地址单元。
start MOV R0,#Ni BL Factorial /*注:在此处观察结果*/
Stop B Stop END
;声明 Factorial 是一个外部函数 ;要计算的阶乘数 ; 声明代码 Fctrl ; 标识程序入口
;将参数装入 R0 ;调用 Factorial,并通过 R0 传递参数
;文件结束
ARM中C语言和汇编语言混合编程_百度文库.
ARM中C语言和汇编语言混合编程在嵌入式系统开发中,目前使用的主要编程语言是C 和汇编,虽然C++已经有相应的编译器,但是现在使用还是比较少的。
在稍大规模的嵌入式程序设计中,大部分的代码都是用C来编写的,主要是因为C语言具有较强的结构性,便于人的理解,并且具有大量的库支持。
但对于一写硬件上的操作,很多地方还是要用到汇编语言,例如硬件系统的初始化中的CPU 状态的设定,中断的使能,主频的设定,RAM控制参数等。
另外在一些对性能非常敏感的代码块,基于汇编与机器码一一对应的关系,这时不能依靠C编译器的生成代码,而要手工编写汇编,从而达到优化的目的。
汇编语言是和CPU的指令集紧密相连的,作为涉及底层的嵌入式系统开发,熟练对应汇编语言的使用也是必须的。
单纯的C或者汇编编程请参考相关的书籍或者手册,这里主要讨论C和汇编的混合编程,包括相互之间的函数调用。
下面分四种情况来进行讨论,不涉及C++语言。
一、在C语言中内嵌汇编在C中内嵌的汇编指令包含大部分的ARM和Thumb指令,不过使用与单纯的汇编程序使用的指令略有不同,存在一些限制,主要有下面几个方面:a 不能直接向PC 寄存器赋值,程序跳转要使用B或者BL指令;b 在使用物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突;c R12和R13可能被编译器用来存放中间编译结果,计算表达式值时可能把R0-R3、R12及R14用于子程序调用,因此避免直接使用这些物理寄存器;d 一般不要直接指定物理寄存器;e 让编译器进行分配内嵌汇编使用的标记是__asm或asm关键字,用法如下:__asm{instruction [; instruction]}或 asm("instruction[; instruction]"。
下面是一个例子来说明如何在C中内嵌汇编语言://C语言文件*.c /procatlaw/#includevoid my_strcpy(const char *src, char *dest{char ch;__asm{loop:ldrb ch, [src], #1strb ch, [dest], #1cmp ch, #0bne loop}}int main({char *a="forget it and move on!";char b[64];my_strcpy(a, b;printf("original: %s", a;printf("copyed: %s", b;return 0;}在此例子中C语言和汇编之间的值传递是用C语言的指针来实现的,因为指针对应的是地址,所以汇编中也可以访问。
ARM汇编语言与C语言混合编程的实现方法
—
聃 _ m
{
isrcin【 nt c o】 nt t ;is ut n u o r i 【 su t n i t ci 】 nr o 】 下 面 通过 一 个 字 符 串复 制 的 侧 子 来 说 明 如 何 在 C中 内 嵌 汇 编 语
#i cu e<sd oh n ld ti.>
21 0 0年
第 3期
S IN E&T C N L GYIF R TON CE C E H O O O MA I N
0本刊重稿0
科技信息
A M汇编语言与 C语言混合编程的实现方法 R
王 应军 曲培新 赵 晨萍 ( 河南科技 学院 河 南 新 乡 4 3 0 ) 5 0 3
【 摘 要】 汇编语言与 c语言在程序设计开发方面各有优劣 , A M 芯片的开发 中采用二者混合编程 可以取长补短 , 在 R 达到最佳效果。 本文
C语言与ARM汇编的混合编程
ATPCS概述 9.1 ATPCS概述
3. 参数传递规则
根据参数个数是否固定,可以将子程序分为参数个数固定的 (nonvariadic)子程序和参数个数可变的(variadic)子程序。ATPCS为 这两种子程序规定了不同的参数传递规则。 参数个数可变的子程序参数传递规则 对于参数个数可变的子程序,当参数不超过4个时,可以使用寄存器 R0~R3来传递参数;当参数超过4个时,还可以使用数据栈来传递参数。 在传递参数时,将所有参数看做是存放在连续的内存单元中的字数据。 然后依次将各名字数据传送到寄存器R0、R1、R2、R3中,如果参数多于 4个,将剩余的字数据传送到数据栈中,入栈时低地址优先,即入栈的顺 序与参数顺序相反,最后一个字数据先入栈。 参数个数固定的子程序参数传递规则 参数个数固定的子程序的参数传递规则为:第一个整数参数按序分配给 R0~R3寄存器,剩余的参数按序分配给堆栈。
从汇编代码中访问C 9.3 从汇编代码中访问C程序全局变量
在ARM汇编代码中只能通过地址间接地访问C程序的全局变量。具体访问方法 是先用IMPORT伪操作声明该全局变量,然后用LDR伪指令将该全局变量的地址 读到一个寄存器中,最后根据变量类型用相应的LDR指令读取该变量的值,用相 应的STR指令修改该变量的值。 对无符号变量用以下对应指令: char类型用LDRB/STRB指令; short类型用LDRH/STRH指令; int类型用LDR/STR指令; 注意,这里是指ARM C(armcc编译器),short类型为16位,int类型为32位, 与标准C有所不同。 对于带符号的变量,则用等价的带符号数操作指令,如LDRSB/LDRSH等。 对于小于8个字的结构性变量,可以通过一条LDM/STM指令来读/写整个变量; 对于结构变量的数据成员,可以使用相应的LDR/STR指令来访问,但必须知道该 结构成员相对于结构变量开始地址的偏移量。
ARM实验四 ARM汇编和C语言混合编程
实验四 ARM汇编和C语言混合编程一,实验目的1.熟悉ADS1.2软件开发环境;2.掌握ARM7TDMI汇编指令的用法,并能编写简单的汇编程序;3.掌握S3C2410A的I/O控制寄存器的配置;4.掌握ARM汇编指令和C语言相互调用的方法。
二,实验设备硬件:PC机一台;软件:Windows98/XP/2000系统,ADS1.2集成开发环境。
三,实验内容1.熟悉ARM开发环境的建立;2.使用ARM汇编和C语言设置GPIO口的相应寄存器。
四,实验步骤C函数中调用汇编实验步骤:1.启动ADS1.2,使用ARM Executable Image工程模板建立一个工程arm2.mcp。
2.建立汇编源文件a.s,编写实验程序,然后添加到工程中。
3.建立汇编源文件b.c,编写实验程序,然后添加到工程中。
4.单步执行程序,运行结果如图6.1~6.4所示。
图6.1 运行结果图6.2 运行结果图6.3 运行结果图6.4 运行结果汇编程序调用C程序实验步骤:1.启动ADS1.2,使用ARM Executable Image工程模板建立一个工程arm3.mcp。
2.建立汇编源文件a.s,编写实验程序,然后添加到工程中。
3.建立汇编源文件b.c,编写实验程序,然后添加到工程中。
4.单步执行程序,运行结果如图6.5~6.9所示。
图6.5 运行结果图6.6 运行结果图6.7 运行结果图6.8 运行结果图6.9 运行结果五,实验总结本次试验主要是加深C语言和汇编混合编程的使用,在一步一步的调试的过程中加深了解并学会使用混合编程。
除此之外,还掌握S3C2410A的I/O 控制寄存器的配置以及ARM汇编指令和C语言相互调用的方法。
本次实验主要是实验二与实验三的结合,由于实验三做的不是很顺利,因此这次实验做的也不是很理想。
第三章 ARM中的C语言和汇编混合编程
ATPCS规定数据栈为FD类型,并对数据栈的操作是8字节 对齐的。异常中断的处理程序可以使用被中断程序的数据 栈,这时用户要保证中断的程序数据栈足够大。下面是一 个数据栈的实例及相关的名称。 数据栈指针:指向最后一个写入栈的数据的内存地址。 数据栈的基地址:是指数据栈的最高地址。 已占用的数据栈:是指数据栈的基地址和数据栈栈指针之 间的区域。 未占用的数据栈:是指数据栈指针和数据栈界限之间的区 域。 数据栈中的数据帧:是指在数据栈中,为子程序分配的用 来保存寄存器和局部变量的区域。
在ARM C语言程序中使用关键词_asm来标识一段汇编指 令程序,基本格式为: _asm { instruction [;instruction] … [instruction] } 在以上的语法中需要指出的是:如果一行中有多个汇编指 令,指令间用分号“;”隔开;如果一条指令占多行,要 使用续行符号“\”;在汇编指令段中可以使用C语言的注释 语句。
3.2 内嵌汇编
使用内嵌汇编可以在C程序中实现C语言不能够完 成的一些操作,同时程序的代码效率也能够比较 高。在内嵌汇编指令包括大部分的ARM指令和 Thumb指令。但是不能够直接引用C语言的变量 定义,数据交换必须通过ATPCS进行。嵌入式汇 编在形式上往往表现为独立定义的函数体。
3.2.1 内嵌汇编的语法格式
对应不同的数据类型要采用不同的LDR/STR指令。 对于unsigned char类型,使用LDRB/STRB访问。 对于unsigned short类型,使用LDRH/STRH访问。 对于unsigned int 类型,使用LDR/STR访问。 对于char类型,使用LDRSB/STRSB访问。 对于short类型,使用LDRSH/STRSH访问。 对于小于8个字的结构型变量,可以通过一条 “LDM/STM”指令来读/写整个变量。 对于结构型变量的数据成员,可以使用相应的 “LDR/STR”指令来访问,这时必须知道该数据成员相对 于结构型变量开始地址的偏移。
