最近,在用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. pmp论坛

    PMP论坛: http://www.px101.com/specialpmp/ http://www.pmp.cn/ http://www.pmptuan.com/ http://www.mypm.n ...

  2. BZOJ3713: [PA2014]Iloczyn

    3713: [PA2014]Iloczyn Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 206  Solved: 112[Submit][Status ...

  3. Linux企业级项目实践之网络爬虫(19)——epoll接口

    由于要实现爬虫程序的快速抓取,显然如果采用阻塞型的I/O方式,那么系统可能很长时间都处在等待内核响应的状态中,这样爬虫程序将大大地降低效率.然而,如果采用非阻塞I/O,那么就要一直调用应用进程,反复对 ...

  4. Struct2(三) Struct2 标签

    在上一篇 Struct2(二)中,我们新建了工程Struct2test用来验证hello World 程序,在index.jsp中,我们添加了一个Struct2 uri 标签用来创建一个指向hello ...

  5. Java中的ThreadLocal深入理解

    提到ThreadLocal,有些Android或者Java程序员可能有所陌生,可能会提出种种问题,它是做什么的,是不是和线程有关,怎么使用呢?等等问题,本文将总结一下我对ThreadLocal的理解和 ...

  6. 下载配置MySql,高速启动MySql批处理,MySQLclient软件SQL-Front的配置---ShinePans

    首先,下载 sql 绿色版,:  http://yunpan.cn/cgERHhTtV8XGh  提取码 85bc 然后解压就可以用, 安装文件夹下有bin文件夹,从里面的命令中启动服务 例如以下: ...

  7. hdu4000 &amp;&amp; hrbust1625

    ikki的数字 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 22(12 users) Total Accepted: 9(8 use ...

  8. 设置程序图标-初识IOS

    相信我们都很喜欢做出的程序弄成自己的图标. 在创建项目过后显示的页面中,选择App lcons and launch images,  点击App lcons Source 之后的方向符号,把里面的东 ...

  9. Hacker(16)----防范端口扫描与嗅探

    端口扫描与嗅探都是黑客常用的招数,其目的是定位目标计算机和窃取隐私信息.为确保自己计算机的安全,用户需要掌握防范嗅探与端口扫描的常见措施,保障个人隐私信息安全. 一.掌握防范端口扫描的常用措施 防范端 ...

  10. python之面向对象(一)

    python编程分为三个阶段: 面向过程编程:根据业务逻辑从上到下垒 函数式编程:将某功能进行函数封装,使用时调用函数即可,减少代码重复量 面向对象编程:对函数进行分类和封装 理论上我们是比较鄙视面向 ...