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文件中的语句根本没有被编译进去,怎么也找不到原因,郁闷

~~

最后在网上搜了个试验程序,把我的程序复制过去,可以编译成功,奇怪了,在我的project里就是不行,我注意到我的project编译后

出现一条WARNING:

*** WARNING L7: MODULE >    MODULE:  8.obj (8)

而同样的程序代码在另外一个project中没有WARNING,肯定是这条WARNING语句导致的,里面提到NAME,难道和名字有关,马上把A51文

件改个名字(原来c文件和a51文件名字一样),编译,哈哈,WARNING不见了,查看汇编代码,一切按预想的进行,唉,一个名字害得我不浅啊

,记住哦,c文件和A51文件不能使用同一个文件名,不过我还不知道为什么会这样,有高手知道得话请告知,还是进行今天的作业吧!

今天说说带参数传递的函数调用,在C51和汇编之间传递参数的方式有两种,一种是通过寄存器传递参数,C51中不同类型的实参会存入

相应的寄存器,在汇编中只需对相应寄存器进行操作,即达到传递参数的目的。

不同类型的数据及其传递参数的寄存器如下表所示:

参数类型 char int long/float 通用指针

第1个 R7 R6&R7 R4-R7 R1-R3

第2个 R5 R4&R5 R4-R7 R1-R3

第3个 R3 R2&R3 -- R1-R3

举个例子吧,void delay(unsigned char i, unsigned int j)  当执行语句delay(10,1000)时,10会存入R7中,1000高位会存入R4中

,低位存入R5中。在汇编语句中从这几个寄存器中取数,再进行操作就行了,说起来也很简单的嘛,呵呵~

来个最简单的实例吧,没什么意义,傻瓜式的程序:

****************************main.c*********************************************

extern void DELAY(unsigned char i,unsigned int j);

main()

{

DELAY(10,1000);

while(1);

}

**********************DELAY.A51********************************************

PR?_DELAY?DELAY     SEGMENT CODE

PUBLIC _DELAY

RSEG  ?PR?_DELAY?DELAY

_DELAY:

DJNZ R4,$

DJNZ R5,$

DJNZ R7,$

RET

END

还要说的是,函数名前要加下划线,表示是有参数传递的函数调用!

4. 函数的返回值传递参数

(2)函数返回值所用的寄存器

返回值类型 寄存器 说明

Bit C 由具体标志位返回

char/unsigned char / 1 byte 指针 R7

int/unsigned int / 2 byte 指针 R6&R7 高位在R6

long/unsigned long / 3 byte 指针 R4-R7 高位在R4

float R4-R7 32bit IEEE格式,指数和符号位在R7

通用指针 R1-R3 存储类型在R3,高位在R2

实例:

********************main.c****************************************

unsigned int example(unsigned char i)

{

return(i*i);

}

main()

{example(80);

#pragma asm

DJNZ R7,$

DJNZ R6,$

#pragma endasm

while(1);

}

函数返回值在R6,R7中。

有时候用到需要精确延时之类的子程序时,用C语言比较难控制,这时候就可以在C中嵌入汇编

比较常用的keil中嵌入汇编的方法如下所示:

如图一,在C文件中要嵌入汇编的地方用#pragma asm和#pragma endasm分隔开来,这样编译时KEIL就知道这中间的一段是汇编了。

在有加入汇编的文件中,还要设置编译该文件时的选项

Generate Assembler SRC File 生成汇编SRC文件

Assemble SRC File 封装汇编文件

(如图三的状态为选中)

选上这两项就可以在C中嵌人汇编了,设置后在文件图示中多了三个红色的小方块。

为了能对汇编进行封装还要在项目中加入相应的封装库文件, 在笔者的项目中编译模式是小模式所以选用C51S.LIB。这也是最常用的。这些库

文件是中KEIL安装目录下的LIB目录中。 加好后就可以顺利编译了。(注:我只在7.0以上版本使用过)

汇编与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等寄存器进行保护的)。

keil4内嵌汇编_keil C中嵌入汇编程序的方法相关推荐

  1. keil5怎么接入汇编_keil C中嵌入汇编程序的方法

    1. C语言中直接嵌入汇编程序段 1.在 C 文件中要嵌入汇编代码片以如下方式加入汇编代码: #pragma ASM ; Assembler Code Here #pragma ENDASM 2.在 ...

  2. ATT汇编语言与GCC内嵌汇编简介

    AT&T汇编语言与GCC内嵌汇编简介 1 AT&T 与INTEL的汇编语言语法的区别 1.1大小写 1.2操作数赋值方向 1.3前缀 1.4间接寻址语法 1.5后缀 1.6指令 2 G ...

  3. GCC如何编译内嵌汇编代码

    内核代码绝大部分使用C  语言编写,只有一小部分使用汇编语言编写,例如与特定体系结构相关的代码和对性能影响很大的代码.GCC提供了内嵌汇编的功能,可以在C代码中直接内嵌汇编语言语句,大大方便了程序设计 ...

  4. MIPS指令集:内嵌汇编asm语法介绍

    目录 一.内嵌汇编基本格式 二.输入操作数和输出操作数 三.破坏描述 四.有名操作数和指定寄存器 五.操作数的修饰符:约束字符 六.内嵌汇编实例:mips系统调用syscall 七.理解 asm vo ...

  5. vs2015c语言内嵌汇编,C#中内嵌资源的读取

    起因 作为一个从Cpper转到C#并且直接从事WPF开发的萌新来说,正式编码过程中碰到了不少问题,一路上磕磕碰碰的.因为软件设计需求上的要求,需要将一些配置文件(XML.INI等)内嵌到程序中,等需要 ...

  6. gnu嵌入汇编,内嵌汇编详细的介绍

    GCC 提供了内嵌汇编的功能,可以在 C 代码中直接内嵌汇编语言语句,大大方便了程序设计.简单的内嵌汇编很容易理解,例: __asm__ __volatile__("hlt"); ...

  7. linux c语言编程内嵌汇编,gcc编译c语言中内嵌汇编

    gcc编译c语言中内嵌汇编 --AT&T and Intel 汇编语法对照 寄存器命名: AT&T:  %eax Intel: eax AT&T 语法源地址在左侧,目的地址在右 ...

  8. GCC在C语言中内嵌汇编 asm __volatile__

    在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可 ...

  9. C语言中内嵌汇编asm语法

    这篇文章写得炒鸡详细而且很全面,易于理解,建议新手查看 C语言中内嵌汇编asm语法 下面这两篇文章作为补充来看 C语言内嵌汇编:asm volatile C语言ASM汇编内嵌语法

最新文章

  1. intval0.57100 php_php中0,'',null,false,true,FLASE,TREU,array()的相等恒等学习
  2. ubuntu14.04.5装cuda7.5记录(解决unable to locate the kernel source,装cuda黑屏问题,装cuda循环登录问题)
  3. Linux下的网络远程安装
  4. 大道至简 23种模式一点就通
  5. matlab-Grefenstette的编码与解码
  6. 成绩排序 九度教程c语言,九度OJ 1089 数字反转
  7. 自定义MongoDB的Spring Social Connect框架
  8. dhtmlXGrid复选框点击事件
  9. C语言 二维数组做函数参数的几种情况
  10. ef mysql 的坑_C# EF 与 MySql 的那些坑
  11. Intel最新路线图:10nm得等2017年底
  12. 进程和应用程序生命周期
  13. SpringBoot学习之文件结构和配置文件
  14. Matlab 2016a 安装及破解教程
  15. java支付管理有源码_一款java版可接入微信、支付宝的三方支付系统项目
  16. 【MIKE21】MIKE21笔记-HD
  17. 17秋 软件工程 团队作业 最终总结博客
  18. EPUB电子书阅读必备
  19. javascript打飞机程序8x8x飞机大战
  20. 中国程序员在德国:海外版抖音火爆,IT 人才稀缺!| 畅言

热门文章

  1. JS代码 是否显示横竖条
  2. 韦小宝适合做IT人的8大理由
  3. 这个AI狠!能互译C++、Java和Python,以后只学一种编程就行吗
  4. C\C++语言,从编程语言到库、API、框架、引擎
  5. mysql dp.cal 显示汉子_计算1到N中各个数字出现的次数 --数位DP
  6. 计算机初级考试题库网络管理,计算机基础考试题库(含答案)
  7. 干货集锦:200+生信范文、30+款软件、12类图片素材PPT,今年的SCI稳了!(附下载)...
  8. 送书 | 人类细胞图谱计划发起人Aviv Regev博士讲单细胞基因组学
  9. linux mysql 临时文件_linux下mysql自动备份数据库与自动删除临时文件
  10. 人工智能 量子力学 时间简史 山海经 三体