打印

keil uv3怎么啦?

[复制链接]
6810|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吧。

使用特权

评论回复
5
ayb_ice| | 2010-4-23 10:32 | 只看该作者
"_NOP(); "如果是多个NOP定义KEIL会调用子程序来代替是正常的

使用特权

评论回复
6
与时俱进|  楼主 | 2010-4-23 12:30 | 只看该作者
请大家仔细看看,LCALL    C:0000
调用的地址是0000-----复位向量!

使用特权

评论回复
7
ayb_ice| | 2010-4-23 13:27 | 只看该作者
//请大家仔细看看,LCALL    C:0000
//调用的地址是0000-----复位向量!

这要看_NOP(); 是怎么定义的嘛。

使用特权

评论回复
8
与时俱进|  楼主 | 2010-4-23 16:45 | 只看该作者
我是没有去定义_NOP();
难道编译器不是把_NOP(); 定义成空操作?
编译器怎么定义_NOP();这个要怎么查?

使用特权

评论回复
9
chen3bing| | 2010-4-23 16:49 | 只看该作者
定义应该在头文件里吧。

使用特权

评论回复
10
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
11
跬步| | 2010-4-23 21:37 | 只看该作者
缺少头文件INTRINS.H      再使用_nop_()

使用特权

评论回复
12
与时俱进|  楼主 | 2010-4-23 21:48 | 只看该作者
我测试了一下,不只是"_NOP();",随便加一个未定义函数都能编译通过,只是给警告。
反汇编都是编译成LCALL 0000。
由此可以推出,Keil不是将_NOP()编译成 LCALL 0000, 而是它根本就不认识什么_NOP();




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

哈哈你真有才啊!

使用特权

评论回复
13
laslison| | 2010-4-23 22:09 | 只看该作者
我还是将信将疑

使用特权

评论回复
14
auzxj| | 2010-4-23 22:18 | 只看该作者
keil里的警告一定程度上是由于自己的疏忽而造成的错误

keil很优秀,它给我的警告我都会认真的分析,每一条都很有意义,从用51的时候我就有这样的习惯:最终版本的工程编译后是不允许有警告的

使用特权

评论回复
15
linjing| | 2010-4-23 22:33 | 只看该作者
这不是编译程序的错
LCALL C:0000 是还没有重定位的指令,程序编译的时候对所有的子程序调用都编译成这样子,因为这时候无论对什么子程序编译程序都不知道它的准确位置,
稍后再进行连接的时候子程序有了确定的地址,就会把0000替换成子程序的实际地址
你可以让Keil编译的时候生成带汇编程序的LST,看一下LST就会明白了
因为你的_NOP子程序没有定义,所以就没有替换

正确的做法请参照11楼

使用特权

评论回复
16
linqing171| | 2010-4-24 07:18 | 只看该作者
11楼正解。
前几天还碰到,一个函数从51移植到arm,又移植回来,里面一个 _nop_
结果第一次移植的时候做了个函数 void _nop_(); 移植回来,看汇编,这个函数被instrins里面的替代了。

还会出现A51 read of address 0的情况,然后异常退出了, 我用的keil c51 9.0.

使用特权

评论回复
17
与时俱进|  楼主 | 2010-4-24 08:23 | 只看该作者
这不是编译程序的错
LCALL C:0000 是还没有重定位的指令,程序编译的时候对所有的子程序调用都编译成这样子,因为这时候无论对什么子程序编译程序都不知道它的准确位置,
稍后再进行连接的时候子程序有了确定的地址 ...
linjing 发表于 2010-4-23 22:33

是已经链接并生成HEX了,然后调试时查看Disassembly窗口发现uv3把
_NOP();          语句编译成   LCALL    C:0000  了

使用特权

评论回复
18
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_();

注意拼写的不同,大小写的不同

使用特权

评论回复
19
jiabin1024| | 2010-4-24 14:00 | 只看该作者
19楼的正解,LZ使用的_NOP(); 是怎么来的呢?

使用特权

评论回复
20
与时俱进|  楼主 | 2010-4-24 20:29 | 只看该作者
确实是不管函数定义与否,都能编译链接通过,最多给个警告。
问题是:编译器这种处理方式不是害人吗?

使用特权

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

本版积分规则

75

主题

1290

帖子

2

粉丝