keil4c语言和汇编混合,keil C语言与汇编语言混合编程
keil C语言与汇编语言混合编程
1. C语言中嵌入汇编
1、在 C 文件中要嵌入汇编代码片以如下方式加入汇编代码:
#pragma ASM
; Assembler Code Here
#pragma ENDASM
2、在 Project 窗口中包含汇编代码的 C 文件上右键,选择“Options for ...”,点击右边的“Generate Assembler SRC File”
和“Assemble SRC File”,使检查框由灰色变成黑色(有效)状态;
3、根据选择的编译模式,把相应的库文件(如 Small 模式时,是 Keil\C51\Lib\C51S.Lib)加入工程中, 该文件必须作为工程的最后文件;
4、编译,即可生成目标代码。
来个实例吧:
#i nclude
void main(void)
{
P2=1;
#pragma asm
MOV R7,#10
DEL:MOV R6,#20
DJNZ R6,$
DJNZ R7,DEL
#pragma endasm
P2=0;
}
2 . 无参数传递的函数调用
C51调用汇编函数
1.无参数传递的函数调用
先来个例子:其中example.c和example.a51为项目中的两个文件
***********************example.c***********************************************
extern void delay100();
main()
{delay100;}
***********************example.a51***********************************************
?PR?DELAY100 SEGMENT CODE; // 在程序存储区中定义段
PUBLIC DELAY100; //声明函数
RSEG ?PR?DELAY100; //函数可被连接器放置在任何地方
DELAY100:
MOV R7,#10
DEL:
MOV R6,#20
DJNZ R6,$
DJNZ R7,DEL
RET
END
在example.c文件中,先声明外部函数,然后直接在main中调用即可。
在example.a51中,
?PR?DELAY100 SEGMENT CODE; 作用是在程序存储区中定义段,DELAY100为段名,?PR?表示段位于程序存储区内
PUBLIC DELAY100; 作用是声明函数为公共函数
RSEG ?PR?DELAY100; 表示函数可被连接器放置在任何地方,RSEG是段名的属性
段名的开头为PR,是为了和C51内部命名转换兼容,命名转换规律如下:
CODE -?PR?
XDATA-?XD
DATA-?DT
BIT-?BI
PDATA-?PD
3. 有参数传递的函数调用
记住哦,c文件和A51文件不能使用同一个文件名,不过我还不知道为什么会这样,有高手知道得话请告知。
今天说说带参数传递的函数调用,在C51和汇编之间传递参数的方式有两种,一种是通过寄存器传递参数,C51中不同类型的实参会存入相应的寄存器,在汇编中只需对相应寄存器进行操作,即达到传递参数的目的。
不同类型的数据及其传递参数的寄存器如下表所示:
在C和汇编混合编程的时候,存在C语言和汇编语言的变量以及函数的接口问题。
在C程序中定义的变量,编译为.asm文件后,都被放进了.bss区,而且变量名的前面都带了一个下划线。在C程序中定义的函数,编译后在函数名前也带了一个下划线。例如:
extern int num就会变成 .bss _num, 1
extern float nums[5]就会变成.bss _nums, 5
extern void func ( )就会变成 _func,
一 汇编和C的相互调用可以分以下几种情况:
(1) 汇编程序中访问c程序中的变量和函数。
在汇编程序中,用_XX就可以访问C中的变量XX了。访问数组时,可以用_XX+偏移量来访问,如_XX+3访问了数组中的XX[3]。
在汇编程序调用C函数时,如果没有参数传递,直接用_funcname 就可以了。如果有参数传递, 则函数中最左边的一个参数由寄存器A给出,其他的参数按顺序由堆栈给出。返回值是返回到A寄存器或者由A寄存器给出的地址。同时注意,为了能够让汇编语言 能访问到C语言中定义的变量和函数,他们必须声明为外部变量,即加extern 前缀。
(2) c程序中访问汇编程序中的变量
如果需要在c程序中访问汇编程序中的变量,则汇编程序中的变量名必须以下划线为首字符,并用global使之成为全局变量。
如果需要在c程序中调用汇编程序中的过程,则过程名必须以下划线为首字符,并且,要根据c程序编译时使用的模式是stack-based model还是register argument model来正确地编写该过程,使之能正确地取得调用参数。
(3) 在线汇编
在C程序中直接插入 asm(“ *** ”),内嵌汇编语句,需要注意的是这种用法要慎用,在线汇编提供了能直接读写硬件的能力,如读写中断控制允许寄存器等,但编译器并不检查和分析在线汇编语言,插入在线汇编语言改变汇编环境或可能改变C变量的值可能导致严重的错误。
二 汇编和C接口中寻址方式的改变:
需 要注意的是,在C语言中,对于局部变量的建立和访问,是通过堆栈实现的,它的寻址是通过堆栈寄存器SP实现的。而在汇编语言中,为了使程序代码变得更为精 简,TI在直接寻址方式中,地址的低7位直接包含在指令中,这低7位所能寻址的具体位置可由DP寄存器或SP寄存器决定。具体实现可通过设置ST1寄存器 的CPL位实现,CPL=0,DP寻址,CPL=1,SP寻址。在DP寻址的时候,由DP提供高9位地址,与低7位组成16位地址;在SP寻址的时候, 16位地址是由SP(16位)与低7位直接相加得来。
由于在C语言的环境下,局部变量的寻址必须通过SP寄存器实现,在混合编程的时候,为了使汇编语言不影响堆栈寄存器SP,通常的方式是在汇编环境中使用DP方式寻址,这样可以使二者互不干扰。编程中只要注意对CPL位正确设置即可
1 .word 的意思就相当与C语言里的int,char等定义一个变两的宽度
2. 编译错误原因有2:
a.如果在汇编里面定义.global(全局符号),那么在C语言里面应该用extern声明,以引用该符号。
b.在汇编里面声明的时候,符号前应加下划线,如 FIQ_Addr: .word EXTint_FIQ 应为: FIQ_Addr: .word _EXTint_FIQ 在C语言里面应用extern声明。 另外,一中方法是,用.ref 代替.global 来声明符号,这样就不用在C源程序里面用extern声明了。 两种方法结果相同。 我讲的是用C和汇编混编程用法,至于C++变量如何翻译成汇编符号可以用仿真器,自己去看,原则类似.
汇编与C语言混合编程的关键问题
1 C程序变量与汇编程序变量的共用
为了使程序更易于接口和维护,可以在汇编程序中引用与C程序共享的变量:
.ref_to_dce_num,_to-dte_num,_to_dce_buff,_to_dte_buff
在汇编程序中引用而在C程序可直接定义的变量:
unsigned char to_dte_buff[BUFF_SIZE];//DSP发向PC机的数据
int to_dte_num;//缓冲区中存放的有效字节数
int to_dte_store;//缓冲区的存放指针
int to_dte_read;//缓冲区的读取指针
这样经过链接就可以完成对应。
2程序入口问题
在C程序中,程序的入口是main()函数。而在汇编程序中其入口由*.cmd文件中的命令决定,如:-e main_start;程序入口地址为main _start。这样,混合汇编出来的程序得不到正确结果。因为C到ASM的汇编有默认的入口c-int00,从这开始的一段程序为C程序的运行做准备工作。这些工作包括初始化变量、设置栈指针等,相当于系统壳不能跨越。这时可在*.cmd文件中去掉语句:-e main_start。如仍想执行某些汇编程序,可以C函数的形式执行,如:
main_start();//其中含有其他汇编程序
但前提是在汇编程序中把_main_start作为首地址,程序以rete结尾(作为可调用的函数)的程序段,并在汇编程序中引用_main_start,即.ref _main_start。
3移位问题
在C语言中把变量设为char型时,它是8位的,但在DSP汇编中此变量仍被作为16位处理。所以会出现在C程序中的移位结果与汇编程序移位结果不同的问题。解决的办法是在C程序中,把移位结果再用0X00FF去“与”一下即可。
4堆栈问题
在汇编程序中对堆栈的依赖很小,但在C程序中分配局部变量、变量初始化、传递函数变量、保存函数返回地址、保护临时结果功能都是靠堆栈完成。而C编译器无法检查程序运行时堆栈能否溢出。
5程序跑飞问题
编译后的C程序跑飞一般是对不存在的存储区访问造成的。首先要查.MAP文件与memory map图对比,看是否超出范围。如果在有中断的程序中跑飞,应重点查在中断程序中是否对所用到的寄存器进行了压栈保护。如果在中断程序中调用了C程序,则要查汇编后的C程序中是否用到了没有被保护的寄存器并提供保护(在C程序的编译中是不对A、B等寄存器进行保护的)。
keil4c语言和汇编混合,keil C语言与汇编语言混合编程相关推荐
- 视频教程-C语言-从汇编角度理解C语言的本质-C/C++
C语言-从汇编角度理解C语言的本质 擅长JavaWeb开发,游戏逆向外挂与反外挂,游戏保护对抗 孙冉 ¥49.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅 ...
- 汇编语言属于C语言吧,汇编语言和c语言的区别是什么
区别:汇编语言的效率高,对硬件的可操控性更强,体积小,不易维护,可移植性很差:c语言的效率比较低,硬件可操控性比较差,目标代码体积大,容易维护,可移植性很好. 汇编语言(Assembly Langua ...
- keil下C与汇编语言混合编程
文章目录 前言 一.在c函数中调用汇编函数 1.调用不带参数的汇编函数 2.调用带形参的汇编函数 二.在汇编函数中调用c函数 三.汇编函数与c函数混合调用 总结 前言 如今C语言很强大,在嵌入式编程当 ...
- C语言和汇编模块化混合编程解决兔子数量问题
文章目录 前言 一.汇编语言操作 二.C语言操作 三.IDA调试 总结 前言 通过C语言调用汇编模块实现C语言和汇编模块化混合编程. 一.汇编语言操作 汇编代码如下: ;c.asm 这个是汇编程序名 ...
- keil4如何将c语言转换成汇编语言_Keil 中关于C语言编译生成汇编代码函数名规则...
在keil 中 C语言的函数有带参数和不带参数之分. 一般的资料里说fun(void)类型的函数不带参数,所以,keil编译器生成的汇编的调用地址(函数名) 为fun.这没有错.事实上,不管C语言的函 ...
- c语言比汇编语言优点,C语言对比汇编的好处.doc
C语言对比汇编的好处 C语言对比汇编的好处 简单来说,C语言对汇编语言进行了抽象,具有如下优点: 更符合人类思维习惯,开发效率高.时间短. 模块化. 可移植性好. 提供数学函数并支持浮点运算. 程序可 ...
- c语言最小点对问题_C语言教程(一):程序开发理论基础!
前言: 1.本系列教程适用于刚开始学习 C 语言的同学,或者初级开发者,或者想系统详细了解 C 语言的小伙伴. 2.本系列教程会从C语言基础到 C 语言高级语法,包含 C 语言所有系列. C语言简介 ...
- keil C对lib封装库反汇编成C语言,Keil软件“C语言”及“汇编”混编 —— 相关知识整理.doc...
Keil软件"C语言"与"汇编"混编 相关知识整理 用Keil在C中嵌入汇编1 在Keil中嵌入汇编2 介绍直接嵌入汇编代码的方法4 采用汇编可能会有的好处5 ...
- keil c语言pdf,Keil软件“C语言”与“汇编”混编 —— 相关知识整理.pdf
Keil软件"C语言"与"汇编"混编 -- 相关知识整理.pdf Keil 软件软件C 语言语言与与汇编汇编混编混编 相关知识整理相关知识整理 用 Keil 在 ...
最新文章
- 添加nginx为系统服务(service nginx start/stop/restart)
- 23种设计模式C++源码与UML实现--中介者模式
- TIBCO Rendezvous — 技术介绍
- Android 撸起袖子,自己封装 DialogFragment
- 破解centos7root口令
- java json 修改字段_我们如何使用Java中的Jackson来更改JSON中的字段名称?
- ios wifi 定位_iOS 中的三种定位方式
- JS基础入门篇(四)—this的使用,模拟单选框,选项卡和复选框
- 拜托,别再让我优化大事务了,我的头都要裂开了
- python 反爬虫策略
- ml-agents与tensorflow结合的先关操作文档
- 晕LIVEnbsp;WRITER设置教程是网易…
- moses中的数据预处理预处理操作
- 微信小程序登录功能wx.login
- mongoose简单了解
- windows 电脑锁屏时,WPS软件自带屏保图片保存的位置
- CSS查漏补缺(一)—页面内容不足铺满屏幕高度和有滚动条时,footer始终保持底部显示
- 产业集群理论及其生态学特性
- js报错 Cannot both specify accessors and a value or writable attribute
- #数据挖掘--第3章:建模调参之支持向量机SVM初体验
热门文章
- 浅谈PS CC 2020——适合新手学习的最新版软件
- SCI期刊名缩写查询的三种方法
- 李永乐复习全书概率论与数理统计 第一、二章 随机事件和概率、随机变量及其概率分布
- 做好网络推广工作需要做出哪些努力?
- et199PHP,[原创]ET199带狗脱壳过程
- artDialog打开一个页面,获取页面元素值
- 详解新网银木马清除技巧
- 用Python将PPT转换PDF
- PowerDVD20中文版|CyberLink PowerDVD Ultra 20中文版 v20.0.2101.62
- 360网页服务器的根目录,360浏览器收藏夹路径在哪里