打印

【技术问题】keil中的那些诡异事件。

[复制链接]
7226|50
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
来了21IC好些阵子了,一直靠发些半灌水贴以求混个脸熟。今天发个纯技术问题求教求教。 如题:hug: 。

1、keil中要对工作寄存器(R0,R1等)进行入栈出栈操作为什么不能直接用如PUSH R0、POP R0这样的写法,要用R0的地址,就是要这样:PUSH 00H、POP 00H?

2、C语言的问题。我写个式子:unsigned int a;    a=(168*196)/10;  结果a=62276,较真实结果大很多,而改成:unsigned int a;   a=168*196; a=a/10; 结果是a=3292;是正确的。  而如果 a=(167*196)/10;  结果也是真确的(167*196是32732,小于int型上限,(168*196)大于int型上限),我明明定义a是unsigned int 型上限是65535,不会越界的。 这是为什么? 不同的写法结果怎么不同?

相关帖子

沙发
cl378454434| | 2011-1-9 20:30 | 只看该作者
貌似LZ不给力啊,比较冷清啊,呵呵

使用特权

评论回复
板凳
xlsbz| | 2011-1-9 20:50 | 只看该作者
本帖最后由 xlsbz 于 2011-1-9 20:54 编辑

第二条  不可能!

如果可能的话,那就是C语言默认强制转换为int型的。


NND,一直以为我c语言基础不错 看样也不咋地!

使用特权

评论回复
地板
rodger_br| | 2011-1-9 20:54 | 只看该作者
我来回答你吧。
1. PUSH、POP不支持寄存器寻址,只支持直接寻址。所以累加器进栈也似乎PUSH ACC,而不是PUSH A。
2. 编译器默认看来是有符号计算,所以你的结果实际上越界了。

使用特权

评论回复
5
原野之狼| | 2011-1-10 00:00 | 只看该作者
1、看汇编指令的寻址方式都有哪几种
2、问题不在于a是有符号还是无符号,而是后面的常数167或168被转化为int来处理。

使用特权

评论回复
6
ayb_ice| | 2011-1-10 08:30 | 只看该作者
这不是诡异事件,而是你不懂...

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
moonsunsun + 1 你懂就说出来呀,让大家明白下 ...
7
刘前辈| | 2011-1-10 09:33 | 只看该作者
本帖最后由 刘前辈 于 2011-1-10 10:02 编辑

谁说keil不支持 PUSH  R0 ;  ?只是你表达错了而已。
     以51为例,51有4个R0, 你 PUSH  R0;想PUSH 哪个R0? 所以你要写清楚:

        PUSH  AR0 ;  //AR0~AR7。 A大概是Address 的意思。
表示语句处由PSW——RSx确定的那个工作寄存器区(0~3)的当前的Rx;看下面:
    PSW_RS0=PSW_RS1=0;   
    PUSH  AR0 ;   
   PSW_RS0=PSW_RS1=1;
    PUSH  AR0 ;

2个推入的AR0是不一样的。


使用特权

评论回复
8
程序医人|  楼主 | 2011-1-10 10:19 | 只看该作者
本帖最后由 程序医人 于 2011-1-10 10:51 编辑
1、看汇编指令的寻址方式都有哪几种
2、问题不在于a是有符号还是无符号,而是后面的常数167或168被转化为int来处理。
原野之狼 发表于 2011-1-10 00:00
   

1、51的工作寄存器其实不是在RAM中吗?这个MOV P1,R0  我觉得其实就是MOV P1,00H,不像8086寄存器是在CPU中的,寄存器没有地址,反正我是认为R0就像00H的一个标号。

2、我把unsigned int 换成unsigned long 和long问题依然,  这下不会越界了吧?

使用特权

评论回复
9
程序医人|  楼主 | 2011-1-10 10:36 | 只看该作者
刘前辈,那招不行的,如果可以应该是编译器里事先定义了AR0这个符号了,我的KEIL里没有。

使用特权

评论回复
10
coody| | 2011-1-10 11:09 | 只看该作者
a =(uint)(168 * 196) / 10;这样就没问题了

使用特权

评论回复
11
twz8858877| | 2011-1-10 11:49 | 只看该作者
51的工作寄存器有4个区,根据PSW的不同,R0实际对应RAM的00H、08H、10H或18H,所以不能直接使用PUSH R0

使用特权

评论回复
12
程序医人|  楼主 | 2011-1-10 11:54 | 只看该作者
感觉LS那种解释有道理,一条相同的指令不可能在不同的时候操作2个不同地址。

使用特权

评论回复
13
程序医人|  楼主 | 2011-1-10 12:19 | 只看该作者
10楼的方法可以,可是为什么?

使用特权

评论回复
14
论坛游客| | 2011-1-10 12:38 | 只看该作者
5楼已经说过原因了

使用特权

评论回复
15
刘前辈| | 2011-1-10 13:56 | 只看该作者
本帖最后由 刘前辈 于 2011-1-10 14:03 编辑
#9楼
       刘前辈,那招不行的,如果可以应该是编译器里事先定义了AR0这个符号了,我的KEIL里没有


呵呵,前辈从不信口瞎说;中国人能想到的,德国人早就想到了。20年前的keil_A51就可以:——别太轻视德国人。

使用特权

评论回复
16
程序医人|  楼主 | 2011-1-10 14:00 | 只看该作者
问题还没解决,就算是被当成int型了,那结果页不会是F344(负数),何况“=”也有自动数据类型转换的。   都说简单,请给个合理的解释呗!  不要说是语法问题,在VC中是没问题的。

使用特权

评论回复
17
程序医人|  楼主 | 2011-1-10 14:15 | 只看该作者
本帖最后由 程序医人 于 2011-1-10 14:17 编辑

前辈请看,AR0(using1的时候)被换成08H了,说明AR0是keil中预先定义的符号。 不是C51指令中的关键字。
您在keil的安装目录中一定能找到此文件。
15# 刘前辈

使用特权

评论回复
18
mohanwei| | 2011-1-10 14:31 | 只看该作者
先把优化级别设置为0(也就是无优化)再测试这种玩意……
在资源本来就紧张的单片机里,如果
int i=0;
i=1;
i=2;
i=3;
i=4;
printf("%d",i);
也要把i折腾一遍再打印出来,那编译器就不用卖了:lol

使用特权

评论回复
19
程序医人|  楼主 | 2011-1-10 14:50 | 只看该作者
我怀疑是在(168*196)/10时编译器直接把浮点数的编码赋值给了x,所以存入x中的是浮点数编码,导致出错。

使用特权

评论回复
20
刘前辈| | 2011-1-10 14:57 | 只看该作者
本帖最后由 刘前辈 于 2011-1-10 15:26 编辑
17#
   前辈请看,AR0(using1的时候)被换成08H了,说明AR0是keil中预先定义的符号。 不是C51指令中的关键字。
您在keil的安装目录中一定能找到此文件。


呵呵,LZ真逗,PUSH 0 是C51语句么?( 可别跟我说uV4 _PUSH_ )看清楚,我写的是aaa.A51.
无论 PUSH   0 还是  PUSH   AR0 都是keil 51汇编语句,和C51有什么关系?
AR0~AR7是keil_Ax51宏汇编器的保留关键字USING 是keil_Ax51汇编器的伪指令。——和C51无关。

你在keil 的安装目录下根本找不到这种预定义文件。
你应该说“AR0(在 using1 的时候)被编译成08H了”,哪有什么预定义转换文件,51 工作寄存器结构都一样,——预定义文件是那种必定要交给用户根据使用需要可修改的,LZ找到这个预定义文件了吗?如果有此文件,还算什么“诡异事件”。

20年前,还没有uV2 _IDE的时候,A51就接受 PUSH   ARx  这样的语句了;我们不知道而已。



/

使用特权

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

本版积分规则

个人签名:程序医人=《程序医人》不是《程序匠人》!

1

主题

220

帖子

0

粉丝