找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2126|回复: 0
打印 上一主题 下一主题
收起左侧

C程序和汇编程序相互调用

[复制链接]
跳转到指定楼层
楼主
ID:107189 发表于 2016-3-6 13:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

     为了使单独编译的C语言程序和汇编程序之间能够相互调用,必须为子程序间的调用规定一定的规则。ATPCS(ARM/Thumb Procedure Call Standard) ,是ARM程序和Thumb程序中子程序调用的基本规则,它规定了一些子程序间调用的基本规则,如想了解更多的规则,可以查看上一篇中关于ATPCS的介绍。

     高级语言函数与汇编语言函数的混合调用也要遵循ATPCS规则,保证程序调用时参数的正确传递。

    当在C语言程序中调用汇编程序时,在汇编程序中使用EXPORT伪指令声明本子程序,使其它程序可以调用此子程序;而在C语言程序中使用extern关键字声明外部函数(声明要调用的汇编子程序),即可调用此汇编子程序。

    当在汇编程序中调用C语言程序时,在C程序中不需要使用任何关键字来声明将被汇编语言调用的C程序,但是在汇编程序调用该C程序之前需要在汇编语言程序中使用IMPORT伪操作来声明该C程序。在汇编程序中通过BL指令来调用子程序。

下面给出两个例子来介绍函数相互调用。

// C程序

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


//定义LED端口寄存器
#define rGPFCON (*(volatile unsigned *)0x56000050) //Port F control
#define rGPFDAT (*(volatile unsigned *)0x56000054) //Port F data
#define rGPFUP (*(volatile unsigned *)0x56000058) //Pull-up control F

extern void delay(int times);                          //声明要调用的汇编子程序
extern void strcpydiy(char *dest, const char *src);    //声明要调用的汇编子程序
extern int callsum(void );                             //声明要调用的汇编子程序


int sumdiy(int a, int b, int c, int d, int e)
{
    return(a+b+c+d+e);
}

void xmain(void)
{

    int temp;

    const char *strsrc = "First string source";
    char strdest[] = "Scend string source";
    printf("Before copying ...:\n");
    printf("%s...%s...\n",strdest,strsrc);
     strcpydiy(strdest, strsrc);
    printf("After copying ...\n");
    printf("%s...%s...\n",strdest,strsrc);

     temp = callsum();
#if 0
    if (temp == 15)
    {
            printf("the sum is :%d\n",temp);

             rGPFCON=(rGPFCON|0xFF00)&0x55FF; //GPF4--GPF7设置为output

              rGPFUP|=0xF0; //disable GPF pull up

              rGPFDAT=(rGPFDAT&0x0F)|0x70;//GPF7 output 0

             while(1);     
    }
#endif

#if 0   
    if(strcmp(strdest,strsrc) == 0)
    {
               rGPFCON=(rGPFCON|0xFF00)&0x55FF;//GPF4--GPF7设置为output
                rGPFUP|=0xF0;                  //disable GPF pull up
                rGPFDAT=(rGPFDAT&0x0F)|0x70;   //GPF7 output 0

               while(1);
    }
#endif
   ...

}

;汇编指令延时程序   
     EXPORT delay                 ;声明本子程序,别的程序可以调用
     EXPORT strcpydiy             ;声明本子程序,别的程序可以调用
     EXPORT callsum               ;声明本子程序,别的程序可以调用
     IMPORT sumdiy               ;声明本程序可以使用C程序中的sumdiy本程序

     AREA DELAY,CODE,READONLY     ;该伪指令定义了一个代码段,段名为Delay,属性只读
;下面是延迟子程序
delay
    sub r0,r0,#1 ;r0=r0-1 r0是入口参数
    cmp r0,#0x0 ;将r0的值与0相比较
    bne delay   ;比较的结果不为0(r0不为0),继续调用delay,否则执行下一条语句
    mov pc,lr    ;返回

strcpydiy
    ;r0为目标字符串地址
    ;r1为源字符串地址
     ldrb r2,[r1],#1
     strb r2,[r0],#1
    cmp r2,#0
     bne strcpydiy
    mov pc,lr

callsum
     stmfd sp!,{lr}   ;返回地址压栈
    mov r0,#0        ;清零,对应sumdiy中的a
    mov r1,#0        ;对应sumdiy中的b
    mov r2,#0        ;对应sumdiy中的c
    mov r3,#0        ;对应sumdiy中的d
    mov r4,#0        ;对应sumdiy中的e

    add r0,r0,#1    ;附初值
    add r1,r1,#2
    add r2,r2,#3
    add r3,r3,#4
    add r4,r4,#5

    str r4,[sp,#-4]! ;r4需要用数据栈来传送
    bl sumdiy        ;调用C函数
    add sp,sp,#4     ;到这里,r0存储了sumdiy的返回值为15
     ldmfd sp!,{pc}

     END ;程序结束符

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表