keil uv3怎么啦?

[复制链接]
7703|23
 楼主| 与时俱进 发表于 2010-4-23 09:39 | 显示全部楼层 |阅读模式
16:                 _NOP();
C:0x0020    120000   LCALL    C:0000
    17:                 _NOP();
C:0x0023    120000   LCALL    C:0000
**************************************
如上面所示,是从Disassembly窗口复制下来的,
也就是说,uv3把
_NOP();          语句编译成   LCALL    C:0000
不管我把优化等级调为0还是9,结果都这样!
 楼主| 与时俱进 发表于 2010-4-23 09:42 | 显示全部楼层
版本是V3.30
ayb_ice 发表于 2010-4-23 09:46 | 显示全部楼层
"_NOP(); "这什么东东
chen3bing 发表于 2010-4-23 10:01 | 显示全部楼层
应该是相当于汇编指令nop吧。
ayb_ice 发表于 2010-4-23 10:32 | 显示全部楼层
"_NOP(); "如果是多个NOP定义KEIL会调用子程序来代替是正常的
 楼主| 与时俱进 发表于 2010-4-23 12:30 | 显示全部楼层
请大家仔细看看,LCALL    C:0000
调用的地址是0000-----复位向量!
ayb_ice 发表于 2010-4-23 13:27 | 显示全部楼层
//请大家仔细看看,LCALL    C:0000
//调用的地址是0000-----复位向量!

这要看_NOP(); 是怎么定义的嘛。
 楼主| 与时俱进 发表于 2010-4-23 16:45 | 显示全部楼层
我是没有去定义_NOP();
难道编译器不是把_NOP(); 定义成空操作?
编译器怎么定义_NOP();这个要怎么查?
chen3bing 发表于 2010-4-23 16:49 | 显示全部楼层
定义应该在头文件里吧。
hgjinwei 发表于 2010-4-23 19:18 | 显示全部楼层
我测试了一下,不只是"_NOP();",随便加一个未定义函数都能编译通过,只是给警告。
反汇编都是编译成LCALL 0000。
由此可以推出,Keil不是将_NOP()编译成 LCALL 0000, 而是它根本就不认识什么_NOP();


C:0x0009    758107   MOV      SP(0x81),#0x07
   196:                 LJMP    ?C_START
C:0x000C    02000F   LJMP     main(C:000F)
    25: void main(void)
    26: {
    27:     _NOP();
C:0x000F    120000   LCALL    C_STARTUP(C:0000)
    28:     ikjkj();
C:0x0012    120000   LCALL    C_STARTUP(C:0000)
    29:     T67676767();
    30:  
    31:  
C:0x0015    120000   LCALL    C_STARTUP(C:0000)
    32:     while(1)  ;
C:0x0018    80FE     SJMP     C:0018


以下是警告
SRC\UART.C(28): warning C206: '_NOP': missing function-prototype

评分

参与人数 1威望 +1 收起 理由
与时俱进 + 1

查看全部评分

跬步 发表于 2010-4-23 21:37 | 显示全部楼层
缺少头文件INTRINS.H      再使用_nop_()
 楼主| 与时俱进 发表于 2010-4-23 21:48 | 显示全部楼层
我测试了一下,不只是"_NOP();",随便加一个未定义函数都能编译通过,只是给警告。
反汇编都是编译成LCALL 0000。
由此可以推出,Keil不是将_NOP()编译成 LCALL 0000, 而是它根本就不认识什么_NOP();




以下是警告 ...
hgjinwei 发表于 2010-4-23 19:18

哈哈你真有才啊!
laslison 发表于 2010-4-23 22:09 | 显示全部楼层
我还是将信将疑
auzxj 发表于 2010-4-23 22:18 | 显示全部楼层
keil里的警告一定程度上是由于自己的疏忽而造成的错误

keil很优秀,它给我的警告我都会认真的分析,每一条都很有意义,从用51的时候我就有这样的习惯:最终版本的工程编译后是不允许有警告的
linjing 发表于 2010-4-23 22:33 | 显示全部楼层
这不是编译程序的错
LCALL C:0000 是还没有重定位的指令,程序编译的时候对所有的子程序调用都编译成这样子,因为这时候无论对什么子程序编译程序都不知道它的准确位置,
稍后再进行连接的时候子程序有了确定的地址,就会把0000替换成子程序的实际地址
你可以让Keil编译的时候生成带汇编程序的LST,看一下LST就会明白了
因为你的_NOP子程序没有定义,所以就没有替换

正确的做法请参照11楼
linqing171 发表于 2010-4-24 07:18 | 显示全部楼层
11楼正解。
前几天还碰到,一个函数从51移植到arm,又移植回来,里面一个 _nop_
结果第一次移植的时候做了个函数 void _nop_(); 移植回来,看汇编,这个函数被instrins里面的替代了。

还会出现A51 read of address 0的情况,然后异常退出了, 我用的keil c51 9.0.
 楼主| 与时俱进 发表于 2010-4-24 08:23 | 显示全部楼层
这不是编译程序的错
LCALL C:0000 是还没有重定位的指令,程序编译的时候对所有的子程序调用都编译成这样子,因为这时候无论对什么子程序编译程序都不知道它的准确位置,
稍后再进行连接的时候子程序有了确定的地址 ...
linjing 发表于 2010-4-23 22:33

是已经链接并生成HEX了,然后调试时查看Disassembly窗口发现uv3把
_NOP();          语句编译成   LCALL    C:0000  了
linjing 发表于 2010-4-24 13:25 | 显示全部楼层
是已经链接并生成HEX了,然后调试时查看Disassembly窗口发现uv3把
_NOP();          语句编译成   LCALL    C:0000  了
与时俱进 发表于 2010-4-24 08:23


_NOP()是一个不存在的子程序,如果你写一个NNOOPP()试试,编译结果同样是LCALL C:0000
正确的处理是

#include <intrins.H>

_nop_();

注意拼写的不同,大小写的不同
jiabin1024 发表于 2010-4-24 14:00 | 显示全部楼层
19楼的正解,LZ使用的_NOP(); 是怎么来的呢?
 楼主| 与时俱进 发表于 2010-4-24 20:29 | 显示全部楼层
确实是不管函数定义与否,都能编译链接通过,最多给个警告。
问题是:编译器这种处理方式不是害人吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

75

主题

1290

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部