Keil中C和汇编混合编程
本文主要参考网上的文章,再进行实践操作整理而成,如有相似之处实属抱歉!在实际应用中有可能基于运行速度的要求可能会在C程序中调用汇编程序,一般不会在汇编程序中调用C程序!不同的编译器具体不同的调用方式,主要取决于编译器本身。下面就说说在Keil C51中怎样实现C程序中调用汇编程序。
在C程序中调用汇编程序一般有两种方法:
1.直接使用编译器提供的参数块
#pragma asm
AsmCode……
#pragma endasm
a. 对工程进行如下设置:
b. 根据Memory Model的选择包含相关的.Lib文件,如当是SMALL模式时包含C51S.LIB。将此文件放入此工程目录下并进行编译链接。网上说一定要放在最后在进行编译才行,经过实验与所放位置无关,可能是编译器版本原因。
2.在C程序中调用汇编函数块
这种情况下又可分为两种形式,一种是带有形参的调用,一种是不带形参的调用,前者相对后者复杂,其实两者不同在于对于参数的保存与调用。
2.1在C程序中调用不带形参的汇编函数
大致思想与C中相差不大,就是在调用文件中先对将调用的汇编函数进行外部声明,再在.a51文件中编写函数的内容,只不过由于要从C过渡到汇编并且要让编译器知道你在做什么所以有些规则就要遵守编译器。下面说说基于Keil4与SI1000的例子:
如我们想调用汇编函数:void asmFun(void),可分为如下几个步骤:
a. 先在源C文件中先定义这个函数,但是不要编写里面的函数体,仅仅是定义而已,然后选择此c源文件的属性让其生成.src文件如下这一步的主要目的是要查看生成的.src汇编文件中asmFun函数的信息,好让我们复制到函数的定义asmFun.a51文件中(这步做完后要将源C文件中的函数定义删除,以及上面的设置也要恢复到原来的状态)。
b. 建立新的汇编源文件*.A51。里面主要包含void asmFun(void)的函数体内容。本例中由于使用的是非常规51内核所以在.A51文件中首先在包含该硬件的头文件如$INCLUDE (REG51Si1000.h),此处要用括号,不然找不到此文件的合法路径,即使用绝对路径也找不到,不知为何!包含此文件后一定要对工程进行如下设置:否则编译器会说你企图重复定义有关的SFR,其实当你找遍整个工程时你都不会发现你有重复定义的问题,问题在于编译器默认情况下就事先已经将传统的基本51内核SFR寄存器做了定义,所以当然它会说你是错的!于是接下来的代码如下(是关于串口设置的),都是从.src文件中复制过来,具体细节不细说,主要是跟编译器有关,自己也有点不是很清楚,主要是查看编译器手册:
?PR?asmFun1?DEMO11 SEGMENT CODE
PUBLIC asmFun
RSEG ?PR?asmFun?DEMO11
asmFun:
CLR EA
MOV SCON0,#010H
SETB ES0
SETB EA
RET
END
c.在C源文件中进行调用。调用之前要先进行外部声明extern void asmFun(void),然后直接调用即可!上述就是不带参数的汇编函数调用,具体过程见附件:
2.2在C程序中调用带形参的汇编函数
在C程序中调用带形参的汇编函数网上有的说的很复杂比较难懂,我就说说很简单的吧!一般C函数的形参翻译成汇编语言后会存储在特定的寄存器与特定的内存中,一般情况下如果函数的形参三个会存储在寄存器中,其它的会存储在特定的内存中,如有特殊情况也会都存储在相关内存中。参数的具体分配如下:
关于内存区分配的形参还不是很明白,暂且不说了,反正就是如果你想在汇编程序中使用相关的形参就直接调用这个形参所存储的寄存器即可,其实和不带形参的方式基本上一样!大致就先说这么多了,还有很多的细节部分需要注意,这要等以后运用的过程中发现问题,然后再解决问题!Keil中有部分解释但不是很清楚,请参阅Keil/hlp/Cx51 Compiler User’s Guide,除非特殊需要否则还是不建议C中调用汇编的做法,因为有点麻烦,大多要依靠编译器本身的特性,容易出错!
网上参考文献:http://hnllei.blog.163.com/blog/static/142039242201142711550874/
怎么有时插图总是插不上啊!
zhuziyu4_518636726 2013-9-30 11:08
用户1602177 2013-9-29 13:39