打印

如何在嵌入的汇编中使用C定义的全局变量

[复制链接]
13962|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
runmo420|  楼主 | 2009-12-30 09:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
冷漠| | 2009-12-30 11:08 | 只看该作者
一个疑问:当你在C程序中用#pragma asm 和#pragma endasm 嵌入汇编代码后,用C51编译程序当然通不过。——这和全局变量没关系。

当你在C程序中用#pragma asm 和#pragma endasm嵌入汇编代码时,必须在C程序头条加入#pragma......

使用特权

评论回复
板凳
yewuyi| | 2009-12-30 11:18 | 只看该作者
_valname行不行?!

使用特权

评论回复
地板
冷漠| | 2009-12-30 13:48 | 只看该作者
本帖最后由 冷漠 于 2009-12-30 13:49 编辑

没个不通过的。看下面示意程序:

#include <reg52.h>
char  ABC;  // 设全局变量 ABC

void main()
{
ABC=0x56;

#pragma   asm    // 嵌入汇编代码
mov   a,  ABC   ; 汇编中使用全局变量
mov   r0,  #10h
mov   r1,  #11h
mov   @r0,  a
mov   @r1,  ABC
nop
nop
#pragma   endasm

while(1);
}

使用特权

评论回复
5
冷漠| | 2009-12-30 13:57 | 只看该作者
编译/汇编结果正常通过的呀。

   110:         MOV     ABC,#056H
   111: ;  
   112: ;  
   113: ; #pragma asm
   114: ; mov a,ABC
C:0x0000    750856   MOV      ABC(0x08),#0x56
   115:           mov a,ABC
   116: ; mov r0,#10h
C:0x0003    E508     MOV      A,ABC(0x08)
   117:           mov r0,#10h
   118: ; mov r1,#11h
C:0x0005    7810     MOV      R0,#0x10
   119:           mov r1,#11h
   120: ; mov @r0,a
C:0x0007    7911     MOV      R1,#0x11
   121:           mov @r0,a
   122: ; mov @r1,ABC
C:0x0009    F6       MOV      @R0,A
   123:           mov @r1,ABC
   124: ; nop
C:0x000A    A708     MOV      @R1,ABC(0x08)
   125:           nop
   126: ; nop
C:0x000C    00       NOP      
   127:           nop
   128: ?C0001:
   129: ; #pragma endasm
   130: ;  
   131: ; while(1);
   132:                         ; SOURCE LINE # 21
C:0x000D    00       NOP      
   133:         SJMP    ?C0001
C:0x000E    80FE     SJMP     C0001(C:000E)
C:0x0010    00       NOP      
C:0x0011    00       NOP      
C:0x0012    00       NOP      
C:0x0013    00       NOP      
C:0x0014    00       NOP      
C:0x0015    00       NOP

使用特权

评论回复
6
呆板书生| | 2009-12-30 14:18 | 只看该作者
如何在嵌入的汇编中使用C定义的全局变量?

先把C文件单独编译,然后去查询编译后产生的对应.lst文件,看那个全局变量名称,例如_valname,

然后,在汇编中定义一个外部的符号,例如,extern  _valname 就可以了,

使用特权

评论回复
7
冷漠| | 2009-12-30 14:30 | 只看该作者

全局变量名字ABC难道在C和汇编码中有2种叫法?

本帖最后由 冷漠 于 2009-12-30 15:12 编辑

书生老师是自己家的独创?嵌入在C模块的汇编代码和C文件是同一模块内的,它们共享同一全局变量名字,——假设全局变量名字为 ABC。即使汇编程序需要说明是外部的,顶多

  EXTRN    DATA(ABC )

而已,还需要到 .LST文件中去查之后才确定这个变量名字叫ABC?
是不是有点多此一举?

KEIL做的编译器没那么逊吧。

使用特权

评论回复
8
yewuyi| | 2009-12-30 15:29 | 只看该作者
印象当中直接在变量名前加个下划线就OVER了。

呵呵,只是印象中,俺顶多嵌入几条NOP指令之流,还真从来没嵌过变量操作的ASM代码呢。。。

使用特权

评论回复
9
yewuyi| | 2009-12-30 15:39 | 只看该作者
经测试,在MPLAB+PICC9.50PL2中,直接在全局变量名前加下划线后编译正确,直接引用变量名则错误。

呵呵,抽空俺再测试IAR下的情况。

俺根本不用KEIL,呵呵,所以KEIL就测试不了拉。。。

使用特权

评论回复
10
呆板书生| | 2009-12-30 17:03 | 只看该作者
9楼正解,

对于大多数编译器来说,C的变量标号,就是前面加个下划线,而且会在编译器的说明中有一节,叫做C和汇编混合中说明,

类似这些,还有函数出入口的参数说明,很详细的。有兴趣的不妨去读一下,这也是C的入门功夫。

我只是为了防止7楼的写法,特意写上查询lst文文件确认。

使用特权

评论回复
11
冷漠| | 2009-12-30 19:01 | 只看该作者
9楼、10楼能不能把实际程序贴出来供大家学习一下?我一直认为,所有的C编译器都是以ANSI C为标准的。无所谓KEIL C51还是其他。

10楼说的“混合编程”是C程序和汇编程序互相调用的技术,遵循另一命名规则。和内嵌汇编码这种简单技术南辕北辙了。

使用特权

评论回复
12
因特网用户| | 2009-12-30 19:33 | 只看该作者
可以生成SRC文件  SRC文件里面可以看到KEIL中的函数和变量的格式声明
如?PR?Ext1_Isr?MAIN表示MAIN.C文件中Ext1_Isr函数,在汇编中声明这个函数为外部函数,就可以用汇编调用这个函数了
变量也是一样的
主要要遵守Keil对变量、函数、参数传递的规则

使用特权

评论回复
13
冷漠| | 2009-12-30 19:49 | 只看该作者

使用特权

评论回复
14
zenwall| | 2009-12-30 20:16 | 只看该作者
俺不知道,来看看。

使用特权

评论回复
15
冷漠| | 2009-12-30 20:18 | 只看该作者

没那么复杂。

LZ那么简单的要求,别引导他到“混合编程”那么高级的解决方案。就像用“回调函数”解决那么简单的修改库问题。说了半天高级解决方案,最好拿出一个实例来。

使用特权

评论回复
16
wuzx-61| | 2009-12-30 20:38 | 只看该作者
借鉴学习了!

使用特权

评论回复
17
冷漠| | 2009-12-30 21:10 | 只看该作者
忽悠人呢:混合编程中加下划线的是函数名,表示此函数带有寄存器参数。还没听说过什么编译器规则自动(不是人为)给全局变量加下划线。

使用特权

评论回复
18
冷漠| | 2009-12-30 21:30 | 只看该作者
本帖最后由 冷漠 于 2009-12-30 21:34 编辑



        9楼在LST文件中证实了编译器给全局变量自动加下划线_ABC ?  如果不能贴出例证,只能怀疑说假话。

使用特权

评论回复
19
runmo420|  楼主 | 2009-12-30 21:35 | 只看该作者
真是谢谢给位大侠了。顺祝大家在即将到来的2010年中工作、学习顺利,生活开心。

使用特权

评论回复
20
desert_hawk| | 2009-12-30 21:39 | 只看该作者
估计是编译器不同,用法也不同,我用IAR试了一下,汇编文件中引用C文件中的变量不用加下划线,直接用变量名就行。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

48

主题

142

帖子

0

粉丝