嵌入式系统实践实验报告--汇编和C 语言的相互调用
第3次实验汇编和C 语言的相互调用 1计算机科学技术系上机实践报告课程名称:嵌入式系统实践 年级:上机实践成绩:指导教师: 姓名:创新实践成绩:上机实践名称:汇编和C 语言的相互调用 学号:上机实践日期:上机实践编号:No.3 组号:上机实践时间:一、 实验目的1. 阅读Embest EduKit-III 启动代码,观察处理器启动过程;2. 学会使用Embest IDE 辅助信息窗口来分析判断调试过程和结果;3. 学会在Embest IDE 环境中编写、编译与调试汇编和C 语言相互调用的程序。二、 实验设备1. 硬件:Embest EDUKIT-III(实验平台) PC机 2. 软件:Embest IDE Pro ARM 集成开发环境,Windows 98/2000/NT/XP。三、 实验内容使用汇编完成一个随机数产生函数,通过 C 语言调用该函数,产生一系列随机数,存放到数组里面。1. C语言的编译过程C语言程序汇编语言程序目标可执行程序2. 汇编语言的函数调用过程参数准备函数返回汇编函数间调用3. 函数调用举例C语言调用汇编函数汇编语言调用C语言函数4. 命令脚本文件和链接脚本文件四、 实验原理1. ARM 过程调用ATPCS(ARM )ATPCS 是一系列用于规定应用程序之间相互调用的基本规则,这此规则包括:支持数据栈限制检查;支持只读段位置无关(ROPI);支持可读/写段位置无关(RWPI);支持ARM 程序和Thumb 程序的混合使用;处理浮点运算。使用以上规定的 ATPCS 规则时,应用程序必须遵守如下:程序编写遵守ATPCS;变量传递以中间寄存器和数据栈完成;汇编器使用-apcs 开关选项。关于其他 ATPCS 规则,用户可以参考ARM 处理器相关书籍或登录ARM 公司网站。程序只要遵守 ATPCS 相应规则,就可以使用不同的源代码编写程序。程序间的相互调用最主要的是解决参数传递问题。应用程序之间使用中间寄存器及数据栈来传递参数,其中,第一个到第四个参数使用R0-R3,多于四个参数的使用数据栈进行传递。这样,接收参数的应用程序必须知道参数的个数。但是,在应用程序被调用时,一般无从知道所传递参数的个数。不同语言编写的应用程序在调用时可以自定义参数传递的约定,使用具有一定意义的形式来传递,可以很好地解决参数个数的问题。常用的方法是把第一个或最后一个参数作为参数个数(包括个数本身)传递给应用程序。ATPCS 中寄存器的对应关系如表35 所列:表 35 ATPCS 规则中寄存器列表2. main() 函数与_gccmain()当应用程序中包含了main()函数,将会引起对C 运行时库的初始化。该初始化是通过函数_gccmain()实现的,即在main()函数入口处,编译器会首先调用_gccmain()函数,然后才是执行编写的代码。_gccmain()函数在gcc 的标准库里面实现。当应用程序中没有包含main()函数,将不会引起对C 运行时库的初始化。这时,C 运行时库的很多功能在应用程序中是不能使用的。在基础实验的课程里面,我们没有涉及到函数库的内容,因此,我们不打算在这里加入函数库的使用。因此,如果我们使用main 函数作为应用程序的主函数,可以在源代码中加入一个空的_gccmain()函数(用C 语言或者汇编语言均可)。图 3-14 explasm 工程文件设置界面五、 实验步骤1. 考本章其他实验,创建新的工程,工程名为:explasm;2. 按照参考程序,重新编写源代码文件并分别保存为randtest.c,init.s,random.s和ldscript,并把它们加入工程里面;3. 参照其他基础实验操作,按照编译 汇编器配置链接器配置调试器配置设置新工程,并编译、链接工程,如图3-14 所示;4. 下载调试文件,打开memory/register/watch/variable/call stack 窗口,单步执行程序。通过以上窗口,跟踪程序运行,观察分析运行结果,通过实验学会使用Embest IDE 进行应用程序的开发与调试;5.理解和掌握实验后,完成实验练习题。6.习题: 编写一个汇编程序mixop.s 实现函数 y=mixop(x1,x2,x3) y=x1+x2*x3 调用c2.c中的multiply函数 C程序1:c1.c 实现函数 void init(); 作为启动时的起始地址 在该函数内要调用mixop函数完成6+40*50,结果存放在变量y中。 C程序2:c2.c 实现函数y=multiply(x1,x2) y=x1*x2 提示:init()函数结尾时,设置死循环 六、 调试过程、结果和分析编写三个函数运行c1.c将常数赋值给r0,r1,r2调用mixop.s保存当前地址将r3的值放入r0将r0*r1的值放入r0R0+r4的结果存入r0七、 总结本次实验主要是将两个C函数与一个汇编函数连接,从而实现相互调用。编译之后调试过程中遇到了一些错误,后来发现是程序入口的地址应该和连接脚本写得一样,之后调试成功。八、 附件c1.cextern int unsignedmixop(int x1,int x2,int x3);void init() int y; y=mixop(6,40,50); while(1) Mixop.s.global mixop.extern multipy.textmixop: mov ip,sp stmdb sp!,fp,ip,lr,pc sub fp,ip,#4 mov r4,r0 mov r0,r2bl multiply add r0,r0,r4 ldmdb fp,fp,sp,pc.endC2.cunsigned int multiply(x1,x2) int y; y=x1*x2; return y;第 8 页 共 8 页