谁帮忙看下这个简单的C51程序

[复制链接]
4758|34
 楼主| yczhang 发表于 2008-1-11 11:40 | 显示全部楼层 |阅读模式
程序如下:&nbsp;void&nbsp;delay(unsigned&nbsp;char&nbsp;i)&nbsp;{&nbsp;while(i--)&nbsp;{&nbsp;;&nbsp;}&nbsp;}&nbsp;main()&nbsp;{&nbsp;unsigned&nbsp;char&nbsp;i,k;&nbsp;while(1)&nbsp;{&nbsp;i=8;&nbsp;delay(i);&nbsp;i=7;&nbsp;delay(i);&nbsp;k=10;&nbsp;}&nbsp;}&nbsp;我想问的是:为什么i=7;那一行程序总是不被编译呢?如下是在伟福界面和keil界面下的图片&nbsp;<img src="https://bbs.21ic.com/upfiles/img/20081/2008111113650434.jpg">&nbsp;<img src="https://bbs.21ic.com/upfiles/img/20081/2008111113726363.jpg">
 楼主| yczhang 发表于 2008-1-11 11:42 | 显示全部楼层

程序

void&nbsp;delay(unsigned&nbsp;char&nbsp;i)<br />{<br />&nbsp;&nbsp;while(i--)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br />main()<br />{<br />&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i,k;<br />&nbsp;&nbsp;while(1)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;i=8;<br />&nbsp;&nbsp;delay(i);<br />&nbsp;&nbsp;i=7;<br />&nbsp;&nbsp;delay(i);<br />&nbsp;&nbsp;k=10;<br />&nbsp;&nbsp;}<br />}<br />编译器的意思是我那行程序i=7;没有用,怎么解决这个问题呢
kine8393 发表于 2008-1-11 11:43 | 显示全部楼层

delay中的WHILE后面要么用;要么用{}

  
 楼主| yczhang 发表于 2008-1-11 11:47 | 显示全部楼层

2

while那块的程序先不用管(以前while后面的括号里有程序的),现在主要的问题是i=7;那行程序怎么总不被编译呢?
dai_weis 发表于 2008-1-11 14:12 | 显示全部楼层

你的 i = 7 后面的 delay(i)

中I是多少?如果是7则编译器认为i=7是个常量,略过了
 楼主| yczhang 发表于 2008-1-11 14:48 | 显示全部楼层

不明白

‘如果是7则编译器认为i=7是个常量’,这句话是什么意思呢,编译器为什么把这个赋值语句当作一个常量呢?
computer00 发表于 2008-1-11 15:22 | 显示全部楼层

实际上是被编译了的,不信你可以看生成的汇编代码。

调用函数时传递的的确是7。没有写回到i倒是事实,因为编译器认为后面不再用i了,所以就没有回写。<br /><br />如果你将下面的k=10改成k=i,那么就会将7写回到i,并且keil编译器不会直接使用立即数7,而用一条减1指令,从前面的8减1变成7。
 楼主| yczhang 发表于 2008-1-11 17:25 | 显示全部楼层

8

汇编程序里果然已经把那行程序编译了,00说的太对了
lby100918 发表于 2008-1-12 23:45 | 显示全部楼层

为什么不把7直接写进去,如:delay(7);

  
ccl_love_u 发表于 2008-1-13 16:05 | 显示全部楼层

oo就是oo

  
sz_kd 发表于 2008-1-13 16:40 | 显示全部楼层

编译过

若将后运行delay()程序中换成<br />while(j--)看看,i一定是7
 楼主| yczhang 发表于 2008-1-13 19:34 | 显示全部楼层

12

回9楼,因为这是我的实验程序,没什么用,主要是一开始没明白不编译i=7;的那个现象
 楼主| yczhang 发表于 2008-1-14 13:02 | 显示全部楼层

还有两段程序

程序1:<br />#include&nbsp;&ltreg52.h&gt<br />sbit&nbsp;bit0=ACC^0;<br />sbit&nbsp;P10=P1^0;<br />main()<br />{<br />&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i,k=0x40;<br />&nbsp;&nbsp;while(1)<br />&nbsp;&nbsp;{ACC=k--;<br />&nbsp;&nbsp;&nbsp;for(i=0;i&lt8;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACC=ACC&gt&gt1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P10=bit0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />}<br />程序2:<br />#include&nbsp;&ltreg52.h&gt<br />sbit&nbsp;bit0=ACC^0;<br />sbit&nbsp;P10=P1^0;<br />main()<br />{<br />&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i,k=0x40;<br />&nbsp;&nbsp;while(1)<br />&nbsp;&nbsp;{ACC=k--;<br />&nbsp;&nbsp;&nbsp;for(i=8;i&gt0;i--)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACC=ACC&gt&gt1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P10=bit0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />}<br />程序的主要目的就是把十六进制数据k串行发送到IO口P1.0。可是如果用程序1就达不到目的,因为程序走到for循环后就把A清0了,而用程序2的话就没事,程序走到for循环后不会把A清0。请问原因是什么?
yexinkfrqw 发表于 2008-1-14 21:25 | 显示全部楼层

这应该是编译器的问题

在反汇编中可以看到后一种ACC的确没有被清0<br />我想应该是编译器代码优化的原因。<br />顶7楼,让学到一种发现问题的好方法!
yixing2003 发表于 2008-1-15 02:02 | 显示全部楼层

volatile

volatile&nbsp;int&nbsp;i;
hotpower 发表于 2008-1-15 02:06 | 显示全部楼层

严重同意楼上~~~

  
 楼主| yczhang 发表于 2008-1-15 11:07 | 显示全部楼层

volatile在这里不管事

我试过加上volatile,不管事的。反正程序1的汇编程序里总是先CLR&nbsp;A,再MOV&nbsp;i,A而程序2的汇编程序就是一个简单的mov&nbsp;i,#8
computer00 发表于 2008-1-15 11:25 | 显示全部楼层

晕...谁叫你C语言里还用ACC啊...晕死..

  
alice84 发表于 2008-1-15 11:29 | 显示全部楼层

使用ACC会被当成汇编吗?

ACC不就是一个名吗/
computer00 发表于 2008-1-15 12:35 | 显示全部楼层

但是它是A累加器...C语言里面本来是看不到这个东西的...

  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

60

主题

454

帖子

0

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