📄 c51和汇编混合编程--wwss.htm
字号:
<DIV id=content>
<TABLE height=13 cellSpacing=0 cellPadding=0 width=490 align=center
border=0>
<TBODY>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD>
<TABLE class=seyle4 cellSpacing=0 cellPadding=0
width="100%" border=0>
<TBODY>
<TR>
<TD> </TD></TR>
<TR>
<TD class=content9 vAlign=center
bgColor=#bbccde><STRONG>C51和汇编混合编程</STRONG></TD></TR>
<TR>
<TD>
<DIV align=right><SPAN class=textbox-label>[
2007-4-10 1:59:00 | By: <SPAN
class=style3>ws19850304</SPAN>
]</SPAN></DIV></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%"
border=0>
<TBODY>
<TR>
<TD height=3> </TD></TR></TBODY></TABLE>
<TABLE style="TABLE-LAYOUT: fixed" cellSpacing=0
cellPadding=0 width="100%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=oblog_text><SPAN
id=ob_logd21914></SPAN>
<DIV> <SPAN
style="FONT-SIZE: 12pt"> </SPAN><STRONG><SPAN
style="FONT-SIZE: 12pt">1. </SPAN><SPAN
style="FONT-SIZE: 12pt">C语言中嵌入汇编</SPAN></STRONG></DIV><BR>
<DIV>1、在 C 文件中要嵌入汇编代码片以如下方式加入汇编代码:<BR>#pragma
ASM<BR>; Assembler Code Here<BR>#pragma
ENDASM<BR><BR>2、在 Project 窗口中包含汇编代码的 C
文件上右键,选择“Options for ...”,点击右边的“Generate Assembler
SRC File”<BR>和“Assemble SRC
File”,使检查框由灰色变成黑色(有效)状态;<BR><BR>3、根据选择的编译模式,把相应的库文件(如
Small 模式时,是 Keil\C51\Lib\C51S.Lib)加入工程中,
该文件必须作为工程的最<BR>后文件;<BR><BR>4、编译,即可生成目标代码。 </DIV>
<DIV>来个实例吧:<BR>#i nclude <reg51.h><BR>void
main(void)<BR>{<BR>P2=1;<BR>#pragma
asm<BR> MOV R7,#10<BR>DEL:MOV
R6,#20<BR> DJNZ
R6,$<BR> DJNZ R7,DEL<BR>#pragma
endasm<BR>P2=0;<BR>}<BR></DIV>
<DIV><SPAN
style="FONT-SIZE: 12pt"><STRONG>2 .
无参数传递的函数调用</STRONG></SPAN></DIV>
<DIV><SPAN
style="FONT-SIZE: 10pt"></SPAN> </DIV>
<DIV><SPAN
style="FONT-SIZE: 10pt">C51调用汇编函数<BR>1.无参数传递的函数调用<BR>先来个例子:其中example.c和example.a51为项目中的两个文件<BR>***********************example.c***********************************************<BR>extern
void delay100();</DIV>
<DIV>
<P>main()<BR>{delay100;}<BR>***********************example.a51***********************************************<BR>?PR?DELAY100
SEGMENT CODE; <SPAN
style="FONT-SIZE: 10pt; COLOR: #ff0000">//
在程序存储区中定义段</SPAN><BR>PUBLIC
DELAY100; <SPAN
style="FONT-SIZE: 10pt; COLOR: #ff0000">//声明函数<BR></SPAN>RSEG
?PR?DELAY100; <SPAN
style="FONT-SIZE: 10pt; COLOR: #ff0000">//函数可被连接器放置在任何地方</SPAN></P>
<P>DELAY100: <BR> MOV
R7,#10<BR>DEL:
<BR> MOV R6,#20<BR> DJNZ
R6,$<BR> DJNZ R7,DEL<BR>
RET<BR>END<BR><BR>在example.c文件中,先声明外部函数,然后直接在main中调用即可。<BR>在example.a51中,<BR>?PR?DELAY100
SEGMENT CODE; 作用是<SPAN
style="FONT-SIZE: 10pt; COLOR: #000000">在程序存储区中定义段,DELAY100为段名,?PR?表示段位于程序存储区内<BR>PUBLIC
DELAY100; 作用是声明函数为公共函数<BR>RSEG
?PR?DELAY100; 表<SPAN
style="FONT-SIZE: 10pt; COLOR: #000000">示函数可被连接器放置在任何地方,RSEG是段名的属性</SPAN><BR></SPAN><SPAN
style="COLOR: #000000">段名的开头为PR,是为了和C51内部命名转换兼容,命名转换规律如下:<BR>CODE
-?PR?<BR>XDATA-?XD<BR>DATA-?DT<BR>BIT-?BI<BR>PDATA-?PD</P>
<P><SPAN style="FONT-SIZE: 12pt"><STRONG>3.
有参数传递的函数调用</STRONG></SPAN></P></SPAN></SPAN></DIV>
<DIV><SPAN style="FONT-SIZE: 12pt"><SPAN
style="FONT-SIZE: 10pt">
在写这片文章之前,写了个试验程序,但总是通不过,查看汇编代码发现c文件中的语句根本没有被编译进去,怎么也找不到原因,郁闷~~ <BR>
最后在网上搜了个试验程序,把我的程序复制过去,可以编译成功,奇怪了,在我的project里就是不行,我注意到我的project编译后出现一条WARNING:<BR><BR>***
WARNING L7: MODULE NAME NOT
UNIQUE<BR> MODULE: 8.obj
(8)<BR><BR>
而同样的程序代码在另外一个project中没有WARNING,肯定是这条WARNING语句导致的,里面提到NAME,难道和名字有关,马上把A51文件改个名字(原来c文件和a51文件名字一样),编译,哈哈,WARNING不见了,查看汇编代码,一切按预想的进行,唉,一个名字害得我不浅啊,记住哦,c文件和A51文件不能使用同一个文件名,不过我还不知道为什么会这样,有高手知道得话请告知,还是进行今天的作业吧!<BR>
今天说说带参数传递的函数调用,在C51和汇编之间传递参数的方式有两种,一种是通过寄存器传递参数,C51中不同类型的实参会存入相应的寄存器,在汇编中只需对相应寄存器进行操作,即达到传递参数的目的。<BR><BR>
不同类型的数据及其传递参数的寄存器如下表所示:<BR> </SPAN></DIV>
<DIV>
<TABLE cellSpacing=0 cellPadding=0 width="43%"
border=1>
<TBODY>
<TR>
<TD width="24%"><SPAN
style="FONT-SIZE: 10pt">参数类型</SPAN></TD>
<TD width="9%"><SPAN
style="FONT-SIZE: 10pt">char</SPAN></TD>
<TD width="16%"><SPAN
style="FONT-SIZE: 10pt">int</SPAN></TD>
<TD width="17%"><SPAN
style="FONT-SIZE: 10pt">long/float</SPAN></TD>
<TD width="42%"><SPAN
style="FONT-SIZE: 10pt">通用指针</SPAN></TD></TR>
<TR>
<TD width="24%"><SPAN
style="FONT-SIZE: 10pt">第1个</SPAN></TD>
<TD width="9%"><SPAN
style="FONT-SIZE: 10pt">R7</SPAN></TD>
<TD width="16%"><SPAN
style="FONT-SIZE: 10pt">R6&R7</SPAN></TD>
<TD width="17%"><SPAN
style="FONT-SIZE: 10pt">R4-R7</SPAN></TD>
<TD width="42%"><SPAN
style="FONT-SIZE: 10pt">R1-R3</SPAN></TD></TR>
<TR>
<TD width="24%"><SPAN
style="FONT-SIZE: 10pt">第2个</SPAN></TD>
<TD width="9%"><SPAN
style="FONT-SIZE: 10pt">R5</SPAN></TD>
<TD width="16%"><SPAN
style="FONT-SIZE: 10pt">R4&R5</SPAN></TD>
<TD width="17%"><SPAN
style="FONT-SIZE: 10pt">R4-R7</SPAN></TD>
<TD width="42%"><SPAN
style="FONT-SIZE: 10pt">R1-R3</SPAN></TD></TR>
<TR>
<TD width="24%"><SPAN
style="FONT-SIZE: 10pt">第3个</SPAN></TD>
<TD width="9%"><SPAN
style="FONT-SIZE: 10pt">R3</SPAN></TD>
<TD width="16%"><SPAN
style="FONT-SIZE: 10pt">R2&R3</SPAN></TD>
<TD width="17%"><SPAN
style="FONT-SIZE: 10pt">--</SPAN></TD>
<TD width="42%"><SPAN
style="FONT-SIZE: 10pt">R1-R3</SPAN></TD></TR></TBODY></TABLE></DIV>
<DIV><BR><SPAN
style="FONT-SIZE: 10pt">
举个例子吧,void delay(unsigned char i, unsigned int
j)
当执行语句delay(10,1000)时,10会存入R7中,1000高位会存入R4中,低位存入R5中。在汇编语句中从这几个寄存器中取数,再进行操作就行了,说起来也很简单的嘛,呵呵~<BR>
来个最简单的实例吧,没什么意义,傻瓜式的程序:</SPAN></DIV>
<P><SPAN
style="FONT-SIZE: 10pt">****************************main.c*********************************************<BR>extern
void DELAY(unsigned char i,unsigned int
j);</SPAN></P>
<DIV><SPAN
style="FONT-SIZE: 10pt">main()<BR>{<BR>DELAY(10,1000);<BR>while(1);<BR>}<BR>**********************DELAY.A51********************************************<BR>?PR?_DELAY?DELAY
SEGMENT CODE <BR>PUBLIC _DELAY<BR>RSEG
?PR?_DELAY?DELAY<BR>_DELAY:<BR>
DJNZ R4,$<BR>
DJNZ R5,$<BR>
DJNZ R7,$<BR>
RET
<BR>END<BR><BR>还要说的是,函数名前要加下划线,表示是有参数传递的函数调用!</SPAN></DIV>
<DIV><SPAN
style="FONT-SIZE: 10pt"></SPAN> </DIV>
<DIV><SPAN style="FONT-SIZE: 10pt"><SPAN
style="FONT-SIZE: 12pt"><STRONG>4. 函数的返回值传递参数</STRONG></SPAN></SPAN></DIV>
<DIV><SPAN
style="FONT-SIZE: 10pt"></SPAN> </DIV>
<DIV><SPAN
style="FONT-SIZE: 10pt">(2)函数返回值所用的寄存器<BR>
</DIV>
<DIV>
<TABLE style="WIDTH: 338px; HEIGHT: 298px"
cellSpacing=0 cellPadding=0 width=338 border=1>
<TBODY>
<TR>
<TD width="30%"><SPAN
style="FONT-SIZE: 10pt">返回值类型</SPAN></TD>
<TD width="11%"><SPAN
style="FONT-SIZE: 10pt">寄存器</SPAN></TD>
<TD width="59%"><SPAN
style="FONT-SIZE: 10pt">说明</SPAN></TD></TR>
<TR>
<TD width="30%"><SPAN
style="FONT-SIZE: 10pt">Bit</SPAN></TD>
<TD width="11%"><SPAN
style="FONT-SIZE: 10pt">C</SPAN></TD>
<TD width="59%"><SPAN
style="FONT-SIZE: 10pt">由具体标志位返回</SPAN></TD></TR>
<TR>
<TD width="30%"><SPAN
style="FONT-SIZE: 10pt">char/unsigned char / 1
byte 指针</SPAN></TD>
<TD width="11%"><SPAN
style="FONT-SIZE: 10pt">R7</SPAN></TD>
<TD width="59%"><SPAN
style="FONT-SIZE: 10pt"> </SPAN></TD></TR>
<TR>
<TD width="30%"><SPAN
style="FONT-SIZE: 10pt">int/unsigned int / 2
byte 指针</SPAN></TD>
<TD width="11%"><SPAN
style="FONT-SIZE: 10pt">R6&R7</SPAN></TD>
<TD width="59%"><SPAN
style="FONT-SIZE: 10pt">高位在R6</SPAN></TD></TR>
<TR>
<TD width="30%"><SPAN
style="FONT-SIZE: 10pt">long/unsigned long / 3
byte 指针</SPAN></TD>
<TD width="11%"><SPAN
style="FONT-SIZE: 10pt">R4-R7</SPAN></TD>
<TD width="59%"><SPAN
style="FONT-SIZE: 10pt">高位在R4</SPAN></TD></TR>
<TR>
<TD width="30%"><SPAN
style="FONT-SIZE: 10pt">float</SPAN></TD>
<TD width="11%"><SPAN
style="FONT-SIZE: 10pt">R4-R7</SPAN></TD>
<TD width="59%"><SPAN
style="FONT-SIZE: 10pt">32bit
IEEE格式,指数和符号位在R7</SPAN></TD></TR>
<TR>
<TD width="30%"><SPAN
style="FONT-SIZE: 10pt">通用指针</SPAN></TD>
<TD width="11%"><SPAN
style="FONT-SIZE: 10pt">R1-R3</SPAN></TD>
<TD width="59%"><SPAN
style="FONT-SIZE: 10pt">存储类型在R3,高位在R2</SPAN></TD></TR></TBODY></TABLE></DIV>
<DIV><BR>实例:<BR>********************main.c****************************************<BR>unsigned
int example(unsigned char
i)<BR>{<BR>return(i*i);<BR>}</DIV>
<DIV>
<P>main()<BR>{example(80);<BR>#pragma asm<BR>DJNZ
R7,$<BR>DJNZ R6,$<BR>#pragma
endasm<BR>while(1);<BR>}<BR><BR>函数返回值在R6,R7中。</P></SPAN></DIV></SPAN></SPAN></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%"
border=0>
<TBODY>
<TR>
<TD height=3> </TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -