第六讲_C与汇编语言混合编程

上传人:油条 文档编号:6684551 上传时间:2017-08-08 格式:PPT 页数:19 大小:90.50KB
返回 下载 相关 举报
第六讲_C与汇编语言混合编程_第1页
第1页 / 共19页
第六讲_C与汇编语言混合编程_第2页
第2页 / 共19页
第六讲_C与汇编语言混合编程_第3页
第3页 / 共19页
第六讲_C与汇编语言混合编程_第4页
第4页 / 共19页
第六讲_C与汇编语言混合编程_第5页
第5页 / 共19页
点击查看更多>>
资源描述

《第六讲_C与汇编语言混合编程》由会员分享,可在线阅读,更多相关《第六讲_C与汇编语言混合编程(19页珍藏版)》请在金锄头文库上搜索。

1、第六讲 C与汇编语言混合编程,C与汇编语言混合编程,ATPCS介绍内嵌汇编C和ARM汇编 程序间相互调用,一、ATPCS介绍,ATPCS(ARM-Thumb Produce Call Standard)是ARM程序和Thumb程序中子程序调用的基本规则,目的是为了使单独编译的C语言程序和汇编程序之间能够相互调用。这些基本规则包括子程序调用过程中寄存器的使用规则、数据栈的使用规则和参数的传递规则。,寄存器的使用规则,子程序间通过寄存器R0R3来传递参数,这时,寄存器R0R3可以记作A1A4。 在子程序中,使用寄存器R4R11来保存局部变量。这时,寄存器 R4R11可以记作V1V8。在Thumb程

2、序中,通常只能使用寄存器R4R7来保存局部变量 。寄存器R12用作子程序间的scratch寄存器(用于保存SP,在函数返回时使用该寄存器出栈),记作ip。 寄存器R13用作数据栈指针,记作sp。 寄存器R14称为链接寄存器,记作lr。 寄存器R15是程序计数器,记作pc。,数据栈的使用规则,根据堆栈指针指向位置的不同 和增长方向的不同可以分为以下4种数据栈 : FD (Full Descending) 满递减 ED (Empty Descending)空递减 FA (Full Ascending) 满递增 EA (Empty Ascending) 空递增ATPCS规定数据栈为FD(满递减)类型

3、,并且对数据栈的操作是8字节对齐的。,参数的传递规则,参数个数固定的子程序参数传递规则: 第一个整数参数,通过寄存器R0R3来传递。其他参数通过数据栈传递。 参数个数可变的子程序参数传递规则: 当参数不超过4个时,可以使用寄存器R0R3来传递参数;当参数超过4个时,还可以使用数据栈来传递参数 子程序结果返回规则: 结果为一个32位的整数时,可以通过寄存器R0返回;结果为一个64位整数时,可以通过寄存器R0和R1返回,依次类推。,二、内嵌汇编,在C程序中嵌入汇编程序可以实现一些高级语言没有的功能,并可以提高执行效率。armcc和armcpp内嵌汇编器支持完整的ARM指令集;tcc和tcpp用于T

4、humb指集。 内嵌的汇编指令包括大部分的ARM指令和Thumb指令,但是不能直接引用C的变量定义,数据交换必须通过ATPCS进行。嵌入式汇编在形式上表现为独立定义的函数体。,内嵌汇编指令的语法格式,_asm(“指令;指令”);ARM C汇编器使用关键字“_asm。如果有多条汇编指令需要嵌入,可以用“”将它们归为一条语句。如:_asm指令;指令指令需要特别注意的是_asm是两个下划线。,内嵌的汇编指令的特点,操作数可以是寄存器、常量或C表达式。它们可以是char、short或者int类型,而且是作为无符号数进行操作 。内嵌的汇编指令中使用物理寄存器有一些限制。常量前的符号“#”可以省略 只有指

5、令B可以使用C程序中的标号,指令BL不能使用C程序中的标号。 不支持汇编语言中用于内存分配的伪操作。指令中如果包含常量操作数,该指令可能会被汇编器展开成几条指令。,内嵌汇编器与armasm汇编器的区别,内嵌汇编器不支持通过“”指示符或PC获取当前指令地址; 不支持LDR Rn,= expression伪指令,而使用MOV Rn, expression指令向寄存器赋值; 不支持标号表达式;不支持ADR和ADRL伪指令; 不支持BX和BLX指令; 不可以向PC赋值; 使用0x前缀替代“”表示十六进制数。,内嵌汇编注意事项,必须小心使用物理寄存器,如R0R3,LR和PC。 不要使用寄存器寻址变量。

6、使用内嵌汇编时,编译器自己会保存和恢复它可能用到的寄存器,用户无须保存和恢复寄存器。 LDM和STM指令的寄存器列表只允许物理寄存器。 汇编语言用“,”作为操作数分隔符,三、C和ARM汇编程序间相互调用,在C和ARM汇编程序之间相互调用必须遵守ATPCS(ARM-Thumb Procedure Call Standard)规则。C和汇编之间的相互调用可以从以下这三方面来介绍:,汇编程序对C全局变量的访问在C语言程序中调用汇编程序在汇编程序中调用C语言程序,汇编程序访问全局C变量,汇编程序可以通过地址间接访问在C语言程序中声明的全局变量。通过使用IMPORT关键词引人全局变量,并利用LDR和ST

7、R指令根据全局变量的地址可以访问它们。对于不同类型的变量,需要采用不同选项的LDR和STR指令,如下所示:,unsigned char LDRB/STRBunsigned short LDRH/STRHunsigned int LDR/STRchar LDRSB/STRSBshort LDRSH/STRSH,AREA globals,CODE,READONLYEXPORT asmsubroutine;IMPORT globvar;asmsubroutineLDR R1,=globvar ;从文字池读globvar的地 ;址,并将其保存到R1LDR R0,R1 ;再将其值读入到寄存器R0中ADD

8、 R0,R0,#2STR R0,R1 ;修改后再将寄存器R0的值 ;赋予变量globvarMOV PC,LREND,在C语言程序中调用汇编程序,为了保证程序调用时参数的正确传递,汇编程序的设计要遵守ATPCS。在汇编程序中需要使用EXPORT伪操作来声明,使得本程序可以被其它程序调用。同时,在C程序调用该汇编程序之前需要在C语言程序中使用extern关键词来声明该汇编程序。,C源程序:# include extern void strcopy(char *d,const char *s) ;用extern声明一个函数为外部函数, ;可以被其他文件中的函数调用。int main() const

9、char *srcstr =“First stringsource”;char * dststr =“Second stringdestination”;strcopy(dststr,srcstr);调用汇编函数strcopy()return(0);汇编源程序:AREA SCopy,CODE,READONLYEXPORT strcopy ;用EXPORT伪操作声明该变量可以被其他 ;文件引用,相当于声明了一个全局变量。 Strcopy ;R0指向目标字符串,R1指向源字符串 LDRB R2,R1,#1 ;字节加载,并更新地址 STRB R2,R0,#1 ;字节保存,并更新地址 CMP R2,#

10、0 ;检测R2是否等于0 BNE strcopy ;若条件不成立则继续执行 MOV PC,LR ;从子程序返回END,在汇编程序中调用C语言程序,为了保证程序调用时参数的正确传递,汇编程序的设计要遵守ATPCS。在C程序中不需要使用任何关键字来声明将被汇编语言调用的C程序,但是在汇编程序调用该C程序之前需要在汇编语言程序中使用IMPORT伪操作来声明该C程序。在汇编程序中通过BL指令来调用子程序。,C函数原型:int g(int a,int b,int c,int d,int e)return a+b+c+d+e;/汇编程序调用C程序g()计算5个整数i, 2*i, 3*i, 4*i, 5*i 的和。 汇编源程序:EXPORT fAREA f,CODE,READONLYIMPORT g;声明该变量函数g( ),i在R0中STR LR,SP,#- 4! ;预先保存LRADD R1,R0,R0;计算2 * i(第2个参数)ADD R2,R1,R0;计算3*i(第3个参数)ADD R3,R1,R2;计算5*i(第5个参数)STR R3,SP,#- 4! ;将第5个参数压人堆栈ADD R3,R1,R1;计算4 * i(第4个参数)BL g ;调用C程序g( )ADD SP,SP,#4 ;调整数据栈指针,准备返回LDR PC,SP,#4 ;从子程序返回END,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 电子/通信 > 综合/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号