﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-franksunny的个人技术空间-随笔分类-概念扫盲</title><link>http://www.cppblog.com/franksunny/category/4835.html</link><description>获得人生中的成功需要的专注与坚持不懈多过天才与机会。

                       ——C.W. Wendte</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 06:10:24 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 06:10:24 GMT</pubDate><ttl>60</ttl><item><title>IP地址与子网掩码</title><link>http://www.cppblog.com/franksunny/archive/2007/08/05/29403.html</link><dc:creator>frank.sunny</dc:creator><author>frank.sunny</author><pubDate>Sun, 05 Aug 2007 14:03:00 GMT</pubDate><guid>http://www.cppblog.com/franksunny/archive/2007/08/05/29403.html</guid><wfw:comment>http://www.cppblog.com/franksunny/comments/29403.html</wfw:comment><comments>http://www.cppblog.com/franksunny/archive/2007/08/05/29403.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/franksunny/comments/commentRss/29403.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/franksunny/services/trackbacks/29403.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;IP地址与子网掩码&nbsp;一般考试中都会给定一个IP地址和对应的子网掩码，让你计算1、子网数目2、网络号3、主机号4、广播地址5、可用IP地址范围碰到这类题，我们应该怎么样来解题呢。方法如下：首先，不要管这个IP是A类还是B类还是C类，IP是哪一类对于解题是没有任何意义的，因为在很多题中B类掩码和A类或是C类网络一起出现，不要把这认为是一个错误，很多时候都是这样出题...&nbsp;&nbsp;<a href='http://www.cppblog.com/franksunny/archive/2007/08/05/29403.html'>阅读全文</a><img src ="http://www.cppblog.com/franksunny/aggbug/29403.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/franksunny/" target="_blank">frank.sunny</a> 2007-08-05 22:03 <a href="http://www.cppblog.com/franksunny/archive/2007/08/05/29403.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于C51内的code，idata，xdata</title><link>http://www.cppblog.com/franksunny/archive/2007/08/05/29393.html</link><dc:creator>frank.sunny</dc:creator><author>frank.sunny</author><pubDate>Sun, 05 Aug 2007 10:19:00 GMT</pubDate><guid>http://www.cppblog.com/franksunny/archive/2007/08/05/29393.html</guid><wfw:comment>http://www.cppblog.com/franksunny/comments/29393.html</wfw:comment><comments>http://www.cppblog.com/franksunny/archive/2007/08/05/29393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/franksunny/comments/commentRss/29393.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/franksunny/services/trackbacks/29393.html</trackback:ping><description><![CDATA[<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><span style="FONT-SIZE: 16pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关于</span><span lang=EN-US style="FONT-SIZE: 16pt">C51</span><span style="FONT-SIZE: 16pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内的</span><span lang=EN-US style="FONT-SIZE: 16pt">code</span><span style="FONT-SIZE: 16pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span><span lang=EN-US style="FONT-SIZE: 16pt">idata</span><span style="FONT-SIZE: 16pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span><span lang=EN-US style="FONT-SIZE: 16pt">xdata<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以前没搞过</span><span lang=EN-US>C51</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，大学时代跟单片机老师的时候也是捣鼓下汇编，现在重新搞单片机，因为手头资料不多，找到一些</span><span lang=EN-US>C51</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的程序，发现里面有这些关键字，不甚明了，没办法只好找了下，发现如下描述：<br></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt; mso-char-indent-count: 2.0"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><br>&nbsp;&nbsp; 从数据存储类型来说，</span><span lang=EN-US style="FONT-SIZE: 12pt">8051</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">系列有<span style="COLOR: red">片内、片外程序存储器，片内、片外数据存储器，片内程序存储器</span>还分<span style="COLOR: red">直接寻址区和间接寻址</span>类型，分别对应</span><span lang=EN-US style="FONT-SIZE: 12pt">code</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US style="FONT-SIZE: 12pt">data</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US style="FONT-SIZE: 12pt">xdata</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US style="FONT-SIZE: 12pt">idata</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以及根据</span><span lang=EN-US style="FONT-SIZE: 12pt">51</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">系列特点而设定的</span><span lang=EN-US style="FONT-SIZE: 12pt">pdata</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型，使用不同的存储器，将使程序执行效率不同，在编写</span><span lang=EN-US style="FONT-SIZE: 12pt">C51</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">程序时，最好指定变量的存储类型，这样将有利于提高程序执行效率</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">此问题将在后面专门讲述</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。与</span><span lang=EN-US style="FONT-SIZE: 12pt">ANSI-C</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">稍有不同，它只分</span><span lang=EN-US style="FONT-SIZE: 12pt">SAMLL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US style="FONT-SIZE: 12pt">COMPACT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US style="FONT-SIZE: 12pt">LARGE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式，各种不同的模式对应不同的实际硬件系统，也将有不同的编译结果。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US>51</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">系列中</span><span lang=EN-US>data,idata,xdata,pdata</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的区别</span><span lang=EN-US><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US>data:</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">固定指前面</span><span lang=EN-US>0x00-0x<st1:chmetcnv UnitName="F" SourceValue="7" HasSpace="False" Negative="False" NumberType="1" TCSC="0" w:st="on">7f</st1:chmetcnv></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US>128</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个</span><span lang=EN-US>RAM</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，可以用</span><span lang=EN-US>acc</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">直接读写的，速度最快，生成的代码也最小。</span><span lang=EN-US><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US>idata:</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">固定指前面</span><span lang=EN-US>0x00-0xff</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US>256</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个</span><span lang=EN-US>RAM,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其中前</span><span lang=EN-US>128</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US>data</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US>128</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">完全相同，只是因为访问的方式不同。</span><span lang=EN-US>idata</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是用类似</span><span lang=EN-US>C</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的指针方式访问的。汇编中的语句为：</span><span lang=EN-US>mox ACC,@Rx.(</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不重要的补充：</span><span lang=EN-US>c</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中</span><span lang=EN-US>idata</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">做指针式的访问效果很好</span><span lang=EN-US>) <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US>xdata:</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">外部扩展</span><span lang=EN-US>RAM</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，一般指外部</span><span lang=EN-US>0x0000-0xffff</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">空间，用</span><span lang=EN-US>DPTR</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">访问。</span><span lang=EN-US><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">pdata:外部扩展RAM的低256个字节，地址出现在A0-A7的上时读写，用movx ACC,@Rx读写。这个比较特殊，而且C51好象有对此BUG，建议少用。但也有他的优点，具体用法属于中级问题，这里不提。</p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<img src ="http://www.cppblog.com/franksunny/aggbug/29393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/franksunny/" target="_blank">frank.sunny</a> 2007-08-05 18:19 <a href="http://www.cppblog.com/franksunny/archive/2007/08/05/29393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]重入和不可重入函数概念浅析</title><link>http://www.cppblog.com/franksunny/archive/2007/08/03/29269.html</link><dc:creator>frank.sunny</dc:creator><author>frank.sunny</author><pubDate>Fri, 03 Aug 2007 04:56:00 GMT</pubDate><guid>http://www.cppblog.com/franksunny/archive/2007/08/03/29269.html</guid><wfw:comment>http://www.cppblog.com/franksunny/comments/29269.html</wfw:comment><comments>http://www.cppblog.com/franksunny/archive/2007/08/03/29269.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/franksunny/comments/commentRss/29269.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/franksunny/services/trackbacks/29269.html</trackback:ping><description><![CDATA[<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><span style="FONT-SIZE: 16pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可重入函数与不可重入函数</span><span lang=EN-US style="FONT-SIZE: 16pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">主要用于多任务环境中，一个可重入的函数简单来说就是可以被中断的函数，也就是说，可以在这个函数执行的任何时刻中断它，转入<span lang=EN-US>OS</span>调度下去执行另外一段代码，而返回控制时不会出现什么错误；而不可重入的函数由于使用了一些系统资源，比如全局变量区，中断向量表等，所以它如果被中断的话，可能会出现问题，这类函数是不能运行在多任务环境下的。<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">也可以这样理解，重入即表示重复进入，首先它意味着这个函数可以被中断，其次意味着它除了使用自己栈上的变量以外不依赖于任何环境（包括<span lang=EN-US>static</span>），这样的函数就是<span lang=EN-US>purecode</span>（纯代码）可重入，可以允许有该函数的多个副本在运行，由于它们使用的是分离的栈，所以不会互相干扰。如果确实需要访问全局变量（包括<span lang=EN-US>static</span>），一定要注意实施互斥手段。可重入函数在并行运行环境中非常重要，但是一般要为访问全局变量付出一些性能代价。<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">编写可重入函数时，若使用全局变量，则应通过关中断、信号量（即<span lang=EN-US>P</span>、<span lang=EN-US>V</span>操作）等手段对其加以保护。<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt"><span style="mso-spacerun: yes">&nbsp;</span></span><span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">说明：若对所使用的全局变量不加以保护，则此函数就不具有可重入性，即当多个进程调用此函数时，很有可能使有关全局变量变为不可知状态。<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">示例：假设<span lang=EN-US>Exam</span>是<span lang=EN-US>int</span>型全局变量，函数<span lang=EN-US>Squre_Exam</span>返回<span lang=EN-US>Exam</span>平方值。那么如下函数不具有可重入性。<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">unsigned int example( int para ) <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">{<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">&nbsp;&nbsp;&nbsp; unsigned int temp;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Exam = para; // </span><span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">（<span lang=EN-US>**</span>）<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; temp = Square_Exam( );<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return temp;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; </span>此函数若被多个进程调用的话，其结果可能是未知的，因为当（<span lang=EN-US>**</span>）语句刚执行完后，另外一个使用本函数的进程可能正好被激活，那么当新激活的进程执行到此函数时，将使<span lang=EN-US>Exam</span>赋与另一个不同的<span lang=EN-US>para</span>值，所以当控制重新回到<span lang=EN-US>&#8220;temp = Square_Exam( )&#8221;</span>后，计算出的<span lang=EN-US>temp</span>很可能不是预想中的结果。此函数应如下改进。<span lang=EN-US><br><br>&nbsp;&nbsp;&nbsp; unsigned int example( int para ) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unsigned int temp;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [</span>申请信号量操作<span lang=EN-US>] //(1)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Exam = para;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; temp = Square_Exam( );<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [</span>释放信号量操作<span lang=EN-US>]<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return temp;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; (1)</span>若申请不到<span lang=EN-US>&#8220;</span>信号量<span lang=EN-US>&#8221;</span>，说明另外的进程正处于给<span lang=EN-US>Exam</span>赋值并计算其平方过程中（即正在使用此信号）<span lang=EN-US>,</span>本进程必须等待其释放信号后，才可继续执行。若申请到信号，则可继续执行，但其它进程必须等待本进程释放信号量后，才能再使用本信号。<span lang=EN-US><br><br>&nbsp;&nbsp;&nbsp; </span>保证函数的可重入性的方法：<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; </span>在写函数时候尽量使用局部变量（例如寄存器、堆栈中的变量），对于要使用的全局变量要加以保护（如采取关中断、信号量等方法），这样构成的函数就一定是一个可重入的函数。<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; VxWorks</span>中采取的可重入的技术有：<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; * </span>动态堆栈变量（各子函数有自己独立的堆栈空间）<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; * </span>受保护的全局变量和静态变量<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; * </span>任务变量<span lang=EN-US><br><br><br>--------------------------------------------------<br>&nbsp;&nbsp;&nbsp; </span>在实时系统的设计中，经常会出现多个任务调用同一个函数的情况。如果这个函数不幸被设计成为不可重入的函数的话，那么不同任务调用这个函数时可能修改其他任务调用这个函数的数据，从而导致不可预料的后果。那么什么是可重入函数呢？所谓可重入函数是指一个可以被多个任务调用的过程，任务在调用时不必担心数据是否会出错。不可重入函数在实时系统设计中被视为不安全函数。满足下列条件的函数多数是不可重入的：<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; 1) </span>函数体内使用了静态的数据结构；<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; 2) </span>函数体内调用了<span lang=EN-US>malloc()</span>或者<span lang=EN-US>free()</span>函数；<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; 3) </span>函数体内调用了标准<span lang=EN-US>I/O</span>函数。<span lang=EN-US><br><br>&nbsp;&nbsp;&nbsp; </span>下面举例加以说明。<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; A. </span>可重入函数<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; void strcpy(char *lpszDest, char *lpszSrc)<o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt"><span style="mso-spacerun: yes">&nbsp;</span>{<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while(*lpszDest++=*lpszSrc++);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *dest=0;<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; B. </span><span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">不可重入函数<span lang=EN-US>1<br>&nbsp;&nbsp;&nbsp; charcTemp;//</span>全局变量<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; void SwapChar1(char *lpcX, char *lpcY)<o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt"><span style="mso-spacerun: yes">&nbsp;</span>{<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cTemp=*lpcX;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *lpcX=*lpcY;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lpcY=cTemp;//</span><span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">访问了全局变量<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; C. </span>不可重入函数<span lang=EN-US>2<br>&nbsp;&nbsp;&nbsp; void SwapChar2(char *lpcX,char *lpcY)<o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt"><span style="mso-spacerun: yes">&nbsp;</span>{<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static char cTemp;//</span><span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">静态局部变量<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cTemp=*lpcX;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *lpcX=*lpcY;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lpcY=cTemp;//</span>使用了静态局部变量<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; </span>问题<span lang=EN-US>1</span>，如何编写可重入的函数？<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; </span>答：在函数体内不访问那些全局变量，不使用静态局部变量，坚持只使用局部变量，写出的函数就将是可重入的。如果必须访问全局变量，记住利用互斥信号量来保护全局变量。<span lang=EN-US><br><br>&nbsp;&nbsp;&nbsp; </span>问题<span lang=EN-US>2</span>，如何将一个不可重入的函数改写成可重入的函数？<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; </span>答：把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写它。其实很简单，只要遵守了几条很容易理解的规则，那么写出来的函数就是可重入的。<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; 1) </span>不要使用全局变量。因为别的代码很可能覆盖这些变量值。<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; 2) </span>在和硬件发生交互的时候，切记执行类似<span lang=EN-US>disinterrupt()</span>之类的操作，就是关闭硬件中断。完成交互记得打开中断，在有些系列上，这叫做<span lang=EN-US>&#8220;</span>进入<span lang=EN-US>/</span>退出核心<span lang=EN-US>&#8221;</span>。<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; 3) </span>不能调用其它任何不可重入的函数。<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; 4) </span>谨慎使用堆栈。最好先在使用前先<span lang=EN-US>OS_ENTER_KERNAL</span>。<span lang=EN-US><br><br>&nbsp;&nbsp;&nbsp; </span>堆栈操作涉及内存分配，稍不留神就会造成益出导致覆盖其他任务的数据，所以，请谨慎使用堆栈！最好别用！很多黑客程序就利用了这一点以便系统执行非法代码从而轻松获得系统控制权。还有一些规则，总之，时刻记住一句话：保证中断是安全的！<span lang=EN-US><br><br>&nbsp;&nbsp;&nbsp; </span>实例问题：曾经设计过如下一个函数，在代码检视的时候被提醒有<span lang=EN-US>bug</span>，因为这个函数是不可重入的，为什么？<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; unsigned int sum_int( unsigned int base ) <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">{<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unsigned int index;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static unsigned int sum = 0; // </span><span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">注意，是<span lang=EN-US>static</span>类型<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (index = 1; index &lt;= base; index++)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sum += index;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return sum;<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; </span>分析：所谓的函数是可重入的（也可以说是可预测的），即只要输入数据相同就应产生相同的输出。这个函数之所以是不可预测的，就是因为函数中使用了<span lang=EN-US>static</span>变量，因为<span lang=EN-US>static</span>变量的特征，这样的函数被称为：带<span lang=EN-US>&#8220;</span>内部存储器<span lang=EN-US>&#8221;</span>功能的的函数。因此如果需要一个可重入的函数，一定要避免函数中使用<span lang=EN-US>static</span>变量，这种函数中的<span lang=EN-US>static</span>变量，使用原则是，能不用尽量不用。<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; </span>将上面的函数修改为可重入的函数，只要将声明<span lang=EN-US>sum</span>变量中的<span lang=EN-US>static</span>关键字去掉，变量<span lang=EN-US>sum</span>即变为一个<span lang=EN-US>auto</span>类型的变量，函数即变为一个可重入的函数。<span lang=EN-US><br>&nbsp;&nbsp;&nbsp; </span>当然，有些时候，在函数中是必须要使用<span lang=EN-US>static</span>变量的，比如当某函数的返回值为指针类型时，则必须是<span lang=EN-US>static</span>的局部变量的地址作为返回值，若为<span lang=EN-US>auto</span>类型，则返回为错指针。</span><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt"><o:p></o:p></span></p>
<img src ="http://www.cppblog.com/franksunny/aggbug/29269.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/franksunny/" target="_blank">frank.sunny</a> 2007-08-03 12:56 <a href="http://www.cppblog.com/franksunny/archive/2007/08/03/29269.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>