最近,在用keil 写一个小程序时,想实践一下从汇编调用 C语言函数,我们都知道C语言调用汇编函数讨论得较多,但反过来,从汇编中调用C语言的函数未见深入分析;在开始的时候,还是忽视了一个问题,就是对现场的保护和还原,以导于程序跑飞。

下面的一个小的测试用例,主要作用是:从C语言程序中调用一个用汇编写的名为int LEDFLASH(int a, int b)。并从该汇编函数中,反过来调言用C语言实现的delay()延时程序。最后的结果是:由P2口控制的LED灯出现闪烁的现象。
 
 C语言源程序所在文件名为:user.c,C语言源程序如下:
 #include <reg52.h>
     void delay(int,int);
 int LEDFLASH(int a,int b);
 void test();
 void main()
 {
    P2 = 0xff;
   while(1)
   LEDFLASH(0xff00,0x0007);
 }
 
 void delay(int a,int b)
 {
  int i,j;
  for(i = 0;i<a;i++)
   for(j= 0;j<b;j++)
    ;
 }
 void test()
 {
   delay(200,245);
   P2 = ~P2;
   delay(201,300);
 }
 
/***************************/
下面是名为afun.asm 的文件,其中实现对LED灯的控制和反调C语言函数。
 
Name TEST1
 
EXTRN CODE(_delay)
 
?PR?LEDFLASHC?XY SEGMENT CODE
 
PUBLIC _LEDFLASH
 
RSEG ?PR?LEDFLASHC?XY 
 
using 0
 
_LEDFLASH:
 
  mov a,r7
  add a,r5
  mov r7,a
  mov a,r6
  add a,r4  ;接收参数并计算
 
  mov r2,ar7
  mov r1,a  ;保存计算结果
 
  push ar7
  push ar6
  push ar5
  push ar4
  push ar3
  push ar2
  push ar1
  push ar0  ;保护现场
 
  mov r7,#200
  mov r6,#0
  mov r5,#200
  mov r4,#0    ;传递延时参数
   
 
  call _delay   ;调用C语言写的延时函数
  pop ar0
  pop ar1
  pop ar2
  pop ar3
  pop ar4
  pop ar5
  pop ar6
  pop ar7   ;还原现场
  mov P2,r2
 
 
  push ar7
  push ar6
  push ar5
  push ar4
  push ar3
  push ar2
  push ar1
  push ar0
 
  mov r7,#200
  mov r6,#0
  mov r5,#200
  mov r4,#0
 
  
 
  call _delay
  pop ar0
  pop ar1
  pop ar2
  pop ar3
  pop ar4
  pop ar5
  pop ar6
  pop ar7
  
  mov a,r2
  cpl a
   
  mov P2, a
  ;MOV P1,r1
  
  RET
  END
 
以上汇编函数中调用C语言函数容易被忽视的地方是在调用(call _delay)时,往往容易遗漏对现场的保护,即对CPU寄存器的保护;在汇编调用C语言实现的delay(int,int)函数前,先对cpu的寄存器进行入栈,调用完后,再进行出栈还原现场。这是因为从汇编调用C语言函数时,C语言函数没有替汇编完成该汇编函数要用到的寄存器(含状态寄存器)等的保护。如果不注意这点,写出来的程序将出现意外。上面例的代码还可以优化,由于只是做一个测试,未进行优化。 在网上也会看到其它少量的讨论从汇编调用C语言函数的文章,还未见有对寄存器进行保护和还原的。

keil or c51 汇编调用c语言函数 容易忽视的问题的更多相关文章

  1. 从linux0.11中起动部分代码看汇编调用c语言函数

    上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...

  2. Matlab调用C语言函数

    Matlab调用C语言函数 如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:double add(double x, double y) { return x + y ;}现在我想要在 ...

  3. C语言中递归什么时候能够省略return引发的思考:通过内联汇编解读C语言函数return的本质

    事情的经过是这种,博主在用C写一个简单的业务时使用递归,因为粗心而忘了写return.结果发现返回的结果依旧是正确的.经过半小时的反汇编调试.证明了我的猜想,如今在博客里分享.也是对C语言编译原理的一 ...

  4. python 调用 C语言函数

    python可以直接调用C语言的函数,本文记录用ctypes调用c语言的方法. test.c #include <stdio.h> int test(char *temp) { print ...

  5. [转]在C#中调用C语言函数(静态调用Native DLL,Windows & Microsoft.Net平台)

    原文:https://blog.csdn.net/yapingxin/article/details/7288325 对于不太了解.Net的人,如果想要了解.Net,我必须给他介绍P/Invoke.P ...

  6. 在Linux上实现Python调用C语言函数

    一般思路 Python中内置ctypes库,需调用c编译成的.so文件来实现函数调用. 假设我们所需调用的c文件名为test.c,文件里有我们需要的函数func(x,y). 将.c文件编译成 .so文 ...

  7. java jni 调用c语言函数

    今日在hibernate源代码中遇到了native关键词,甚是陌生,就查了点资料,对native是什么东西有了那么一点了解,并做一小记. native关键字说明其修饰的方法是一个原生态方法,方法对应的 ...

  8. python 调用c语言函数

    虽然python是万能的,但是对于某些特殊功能,需要c语言才能完成.这样,就需要用python来调用c的代码了 具体流程: c编写相关函数 ,编译成库 然后在python中加载这些库,指定调用函数. ...

  9. 【Python】python 调用c语言函数

    虽然python是万能的,但是对于某些特殊功能,需要c语言才能完成.这样,就需要用python来调用c的代码了具体流程:c编写相关函数 ,编译成库然后在python中加载这些库,指定调用函数.这些函数 ...

随机推荐

  1. PSAM 卡的应用操作方法

    PSAM 卡的应用        PSAM 功能 终端安全存储模块        PASM  常用于 脱机交易的 安全认证        脱机交易的流程          1.卡片对持卡人的认证(防止 ...

  2. 自制单片机之十……AT89S51的上拉电阻问题

    很多网友都问我AT89S51的P0口为什么要接一个上拉电阻.我就用一个篇幅来说一说 P0口和其它三个口的内部电路是不同的,如下图 P0口是接在两个三极管D0和D1之间的,而P1-P3口的上部是接一个电 ...

  3. UML--对象的介绍

    UML相对于学习UML的符号含义而言,掌握它们背后的方法和思想是更为重要的.软件是一种实践知识,仅仅靠书本不可能成为高手.书本只能给出思路和知识点,而掌握和消化这些知识则必须在实践中去完成. 如果我们 ...

  4. opencv视频跟踪2

    在前面的报告中我们实现了用SURF算法计算目标在移动摄像机拍摄到的视频中的位置.由于摄像机本身像素的限制,加之算法处理时间会随着图像质量的提高而提高,实际实验发现在背景复杂的情况下,结果偏差可能会很大 ...

  5. spring 配置文件XSD地址

    这边部署不能访问外网,所以sping配置文件里的XSD地址要改一下象  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd ...

  6. c语言sizeof与strlen的区别

    #include <stdio.h> #include <stdlib.h> #include <string.h> //strlen与sizeof的区别 //st ...

  7. ubuntu14.04 + cocos2d-x-2.2.6 + eclipse发布android + Qt Creator4

    先把需要的东西准备好,打开控制台,执行以下语句: sudo apt--jdk lib32z1 lib32ncurses5 lib32bz2- 接下来,准备好cocos2d-x-2.2.6和 andro ...

  8. 初入Python继承

    1.什么是继承? 新类不用从头编写 新类从现有的类继承,就自动拥有了现有类的所有功能 新类只需要编写现有类缺少的新功能 2.继承的好处 复用已有代码 自动拥有了现有类的所有功能 只需要编写缺少的新功能 ...

  9. 推荐C/C++常见的面试题目

    http://blog.163.com/bingqingyujie..5/blog/static/75559361201011861958534/ 里面有详细的面试类型

  10. jsf标签,jsp标签与jstl标签

    JSF通过定制标签与JSP集成.之前展示过的所有 JSF标签,<h:inputText>.<h:outputText>.<h:form> 和<f:view&g ...