汇编语言与C语言混合编程教学初探
2016-12-23程和生程和侠刘路路
程和生,程和侠,刘路路
(1.合肥师范学院 计算机学院, 安徽 合肥 230601;2.安庆师范大学 计算机与信息学院, 安徽 安庆 246011)
汇编语言与C语言混合编程教学初探
程和生1,程和侠2,刘路路1
(1.合肥师范学院 计算机学院, 安徽 合肥 230601;2.安庆师范大学 计算机与信息学院, 安徽 安庆 246011)
汇编语言和C语言结合教学方式,可提高学生对汇编语言学习的兴趣,还可体会到汇编语言直接控制底层的便利和运行效率高。根据教学实践,列举具体实例,涉及具体的编译器对C语言和汇编语言的规定。汇编语言与C语言中的变量和函数彼此之间相互调用方法。实际的教学实践证明受到良好的效果。
汇编语言是一种初级计算机语言,不同中央处理器具有对应配套的汇编指令集合。汇编语言开发应用程序,管理难度大,开发成本高。随着计算机技术的发展,计算机语言也跟随改进,从与硬件相关的机器语言和汇编语言,发展到面向对象的高级语言。计算机高级语言更加的接近人们的思维方式,更加容易实现功能[1,2]。汇编语言似乎失去了存在的意义,“汇编语言”课程教学存在了质疑。
随着嵌入式技术的发展,嵌入式系统在有限的硬件资源,要求达到理想的处理速度,此时汇编语言与高级语言混合编程的方式是一个比较好的选择[3]。汇编语言具有代码生成效率高,运行速度快,方便直接控制底层资源、占用存储空间小等优点,但是与具体的硬件相关,移植性差[4]。C语言是过程性语言典型代表,具有通俗易懂,移植性良好等特点[5]。
本文以ARM为平台,针对汇编语言教学中涉及到混合编程情况,介绍C语言和汇编语言混合编程的基本使用方法。
C语言与汇编混合编程,一般分两种情况:
(1) 汇编代码比较短,在C语言代码中嵌入汇编代码,实现混合编程。
(2)汇编语言比较长,以汇编文件的形式,根据ATPCS协议,实现C语言调用和访问。
本文第一部分介绍编译器对汇编语言和C语言之间是如何切换,了解混合编程的内部实现,方便后续内容的理解。第二部分介绍汇编语言与C语言如何相互调用变量并给出实例。第三部分介绍汇编语言与C语言如何实现互相调用函数并给出实例。
1 编译器对混合编程规定
每个处理器都有相关编译规定,ARM平台采用是ATPCS(ARM/ThumbProcedureCallStandard)。规定了汇编语言和C语言等之间的调用和切换。规定如下。
(1) 参数传递
少于等于4个参数,使用寄存器R0,R1,R2,R3传递;多出参数使用堆栈传递。实际使用中尽量使用不多于4个参数。返回参数是1个32位整数,通过R0返回;返回参数是1个64位整数,通过R0和R1返回;浮点数通过F0寄存器返回。
(2) 堆栈规则
对堆栈规则采用小端制方式,栈顶是高地址,每插入一个元素,地址自动减小;出栈操作时,地址自动增加。
(3) 使用寄存器规则
寄存器的使用严格按照ATPCS的要求调用,具体的限制如表1所示。
表1 编译器对寄存器的规定
2 汇编语言与C语言互调变量
2.1 汇编语言访问C语言变量
高级机器语言中声明的全局变量,汇编程序可通过地址间接访问。具体访问方法和步骤如下,以C语言全局变量Val为例:
(1) 在C程序中声明全局变量Val;
(2) 使用IMPORT/EXTERN汇编伪指令,引用此变量Val;
(3) 汇编语言的LDR伪指令获取变量Val实际地址;
(4) 对不同的数据类型,采用匹配STR指令获取变量Val数值。
如下列举教学实例,实现上述汇编语言调用C语言定义的变量Val并实现变量Val自身加1和保存:
AREAExample4,CODE,READONLY
EXPORTAddNext
IMPORTVal@声明在C语言中定义的变量Val
AddNext
LDRR1, =Val@装载变量地址
LDRR0, [R1] @从地址中读取数据到R0
ADDR0,R0, #1 @加1操作
STRR0, [R1] @保存变量值
MOVPC,LR@程序返回
END
2.2 C语言访问汇编程序数据
在汇编程序中声明的数据可以被C程序所访问。具体访问方法/步骤如下:
(1) 在汇编程序中用EXPORT/GLOBAL伪指令声明该符号为全局标号,可以被其他文件应用。
(2)C程序中定义相应数据类型的指针变量。
(3) 对该指针变量赋值为汇编程序中的全局标号,利用该指针访问汇编程序中的数据。
假设在汇编程序中定义了一块内存区域,并保存一串字符,汇编代码如下:
EXPORTMessage@声明全局标号
MessageDCB"HELLO$" @定义了5个有效字符,$为结束符
externchar*Message;
intMessageLength()
{
intLength= 0;
char*pMessage; //定义字符指针变量
pMessage=Message; //指针指向Message内存块的首地址
/*while循环,统计字符串的长度*/
while(*pMessage!= '$') //$为字符串的结束符
{
Length++;
pMessage++;
}
return(Length); //返回字符串的长度
}
以上代码主要功能是,C语言中统计汇编中字符串Message含的字符个数。
3 汇编语言与C语言的函数相互调用
函数的交叉调用必须遵循ATPCS规则,其规定汇编程序调用C语言定义函数需要满足下列3个条件:
(1) 代码格式采用ATPCS规则。
(2) 堆栈的使用要遵守相应的ATPCS规则。
(3) 在汇编编译器中使用]atpcs选项。
3.1 C程序调用汇编程序
汇编程序格式遵循ATPCS规则,满足参数传递正确性,以函数fun为例,具体步骤如下:
(1) 使用EXPORT伪指令声明汇编中子程序fun,此时其具有外部调用属性;
(2)C语言中extern关键字声明汇编定义函数fun,C程序才可调用函数fun。
#include
externvoidstrcopy(char*d,constchar*s);
intmain(void)
{
constchar*srcstr= "Firstource"; //定义字符串常量
chardststr[] = "Secondstring]destination"; //定义字符串变量
printf("Beforecopying: ");
printf("src=%s,dst=%s ",srcstr,dststr);
strcopy(dststr,srcstr); //调用汇编子程序R0=dststr,R1=srcstr
printf("Aftercopying: ");
printf("src=%s,dst=%s ",srcstr,dststr); //显示复制后的结果
return(0);
}
strcopy实现代码如下:
AREAExample,CODE,READONLY@声明代码段Example
EXPORTstrcopy@声明strcopy,以便外部函数调用
strcopy@R0为目标字符串的地址,R1为源字符串的地址
LDRBR2, [R1], #1 @读取字节数据,源地址加1
STRBR2, [R0], #1
CMPR2, #0 @判断字符是否复制完毕
BNEstrcopy@没有复制完,继续循环复制
MOVPC,LR
以上代码功能,实现在C程序中调用汇编程中定义的strcopy函数。
3.2 汇编程序调用C程序
汇编程序设置要遵循APTCS规则。汇编程序调用C程序的方法如下:
(1) 伪指令IMPORT声明C程序函数;
(2)C代码中,入口参数正确,采用BL指令调用。
列举实例如下,功能是在汇编程序调用C程序中的求和函数sum:
intsum(inta,intb,intc,intd,inte)
{
return(a+b+c+d+e); //返回5个变量的和
}
AREAExample,CODE,READONLY
IMPORTsum@声明外部标号sum,即C函数sum()
EXPORTCALLSUM
CALLSUM
STMFDSP!, {LR} @LR寄存器入栈
MOVR0, #1 @设置sum函数入口参数,R0为参数a
MOVR1, #2 @R1为参数b
MOVR2, #3 @R2为参数c
MOVR3, #5 @参数e=5,保存到堆栈中
STRR3, {SP, #]4}!
MOVR3, #4 @R3为参数d,d=4
BLsum@调用sum函数
ADDSP,SP, #4 @调整堆栈指针
LDMFDSP, {PC} @程序返回
END
4 总结
在汇编语言的教学受到质疑情况下,将C语言与汇编语言结合教学可以有效的提高系统的运行效率,也可以让学生更好的掌握软件控制硬件的方法。论文主要阐述了汇编语言与C语言彼此之间的变量和函数的互相调用。通过近几年的教学情况反馈,具有一定的成效,以后的工作中进一步探索,结合相关知识,让学生更容易地掌握和吸收。
[1] 郑利平, 周国祥, 张冬艳,等. 结合高级语言的汇编语言教学方法研究[J]. 合肥工业大学学报:社会科学版, 2008, 22(5):101]105.
[2] 王有远, 戴红星. 汇编语言与C语言的接口技术[J]. 智能计算机与应用, 2000(1):31]32.
[3] 张永, 黄建字, 刘治生.C语言与汇编语言混合编程的研究与实现[J]. 计算机与数字工程, 2006, 34(5):120]122.
[4] 刁红军, 杨季文. 汇编语言实验教学与实践[J]. 计算机教育, 2015(15).
[5] 曹烨. 浅谈C语言与汇编语言混合编程的实现[J]. 科技信息:科学教研, 2008(17).
2016-06-25
合肥师范学院青年基金项目(2015QN12)资助
程和生(1985-), 男, 合肥师范学院计算机学院硕士研究生,教师, 主要研究方向: 信号与信息处理。
G
B
1674-2273(2016)06-0084-03