我研究一上午,写了个程序,可谓麻雀虽小可五脏俱全,希望正在学习这块的人能少找点资料,少花点时间更快的掌握。
#include <reg52.h>
/****在汇编中定义*****/
extern void delay(void) ;
extern add(int a,int b);
//测试汇编调用的代码(不想直接用汇编来走主程序)
extern void test();
/***在汇编中定义的代码段****/
extern unsigned char cc;
// C语言中定义的函数
void delay_c();
unsigned int addcc(unsigned int wd1,unsigned int wd2);
//C语言中定义的数据段
unsigned int aa;
unsigned int bb;
void main()
{
delay();
cc=add(10,15);
test();
while(1);
}
void delay_c()
{
unsigned char cc;
cc=0xff;
while(cc--);
}
unsigned int addcc(unsigned int wd1,unsigned int wd2)
{
unsigned int cl;
cl=wd1+wd2;
return cl;
}
delay.asm
NAME ONE ;模块的名称
;ORG 1000H ;函数存放的起始单元
?PR?delay?ONE SEGMENT CODE ;标注函数的定义位置
?PR?_add?ONE SEGMENT CODE
?PR?test?ONE SEGMENT CODE
cc DATA 33H ;直接 定义数据的地址
PUBLIC delay ;声明为全局
PUBLIC _add
PUBLIC test
PUBLIC cc ;声明全局
EXTRN DATA(aa) ;注意这里是extrn 而不是C中extern 在 c中定义
EXTRN DATA(bb)
EXTRN CODE(delay_c)
EXTRN CODE(_addcc) ;带参数的网上的资料EXTRN CODE(addcc) 我没测试成功。按理名字应该加_fun 这个是带参的定义方式
;EXTRN DATA(?_addcc?BYTE) ;网上传参通过这个我也没试成功,直接对寄存器做数据的处理了。
RSEG ?PR?delay?ONE ;(不带参函数)重新定位函数的代码位置
delay:
MOV R0 , #44H
DJNZ R0,$
RET
RSEG ?PR?_add?ONE ;(带参函数)参数自动防止到寄存器中可以网上查下,这里 15分别存放到R7,R6 10存入R5,R4
_add:
MOV A,R5
ADD A,R7
MOV R7,A
MOV A,R4
ADDC A,R6
MOV aa,R7
RET
RSEG ?PR?test?ONE
test:
;掉用不带参数的C函数
CALL delay_c
;调用带参数的C函数
MOV R5,#15
MOV R7,#11
LCALL _addcc
MOV cc,R7
RET
END ;程序结束
