📄 dpjjx12.htm
字号:
<P ALIGN="JUSTIFY">.</P>
<P ALIGN="JUSTIFY">TABLE:	DB 0,1,4,9,16,25</P>
</FONT><P ALIGN="JUSTIFY"><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>设</font><FONT SIZE=3>R0</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值为</FONT><FONT SIZE=3>2</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,送入</FONT><FONT SIZE=3>A</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中,而</FONT><FONT SIZE=3>DPTR</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值则为</FONT><FONT SIZE=3>TABLE</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,则最终确定的</FONT><FONT SIZE=3>ROM</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>单元的地址就是</FONT><FONT SIZE=3>TABLE+2</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,也就是到这个单元中去取数,取到的是</FONT><FONT SIZE=3>4</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,显然它正是</FONT><FONT SIZE=3>2</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>的平方。其它数据也可以类推。</font></P><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"><HR ALIGN="RIGHT" WIDTH="4%" SIZE=1><HR ALIGN="RIGHT" WIDTH="4%" SIZE=1><HR ALIGN="RIGHT" WIDTH="4%" SIZE=1>标号的真实含义:从这个地方也可以看到另一个问题,我们使用了标号来替代具体的单元地址。事实上,标号的真实含义就是地址数值。在这里它代表了,</FONT><FONT SIZE=3>0</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>1</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>4</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>9</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>16</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>25</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>这几个数据在</FONT><FONT SIZE=3>ROM</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中存放的起点位置。而在以前我们学过的如</FONT><FONT SIZE=3>LCALL DELAY</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指令中,</FONT><FONT SIZE=3>DELAY </FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>则代表了以</FONT><FONT SIZE=3>DELAY</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>为标号的那段程序在</FONT><FONT SIZE=3>ROM</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中存放的起始地址。事实上,</FONT><FONT SIZE=3>CPU</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>正是通过这个地址才找到这段程序的。<p></P>
<P ALIGN="JUSTIFY"><HR ALIGN="RIGHT" WIDTH="4%" SIZE=1>可以通过以下的例子再来看一看标号的含义:<p></P>
<P ALIGN="JUSTIFY"><HR ALIGN="RIGHT" WIDTH="4%" SIZE=1></FONT><FONT SIZE=3>MOV DPTR</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>#100H<p></P>
</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY"><HR ALIGN="RIGHT" WIDTH="4%" SIZE=1></FONT><FONT SIZE=3>MOV A</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>R0<p></P>
</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY"><HR ALIGN="RIGHT" WIDTH="4%" SIZE=1></FONT><FONT SIZE=3>MOVC A</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>@A+DPTR<p></P>
</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY"><HR ALIGN="RIGHT" WIDTH="4%" SIZE=1></FONT><FONT SIZE=3>.<p></P>
</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY"></P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">ORG 0100H.</P>
<P ALIGN="JUSTIFY">	DB 0,1,4,9,16,25</P>
</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY"></P>
</FONT><P ALIGN="JUSTIFY"><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>如果</font><FONT SIZE=3>R0</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值为</FONT><FONT SIZE=3>2</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,则最终地址为</FONT><FONT SIZE=3>100H+2</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>为</FONT><FONT SIZE=3>102H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,到</FONT><FONT SIZE=3>102H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>单元中找到的是</FONT><FONT SIZE=3>4</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>。这个可以看懂了吧?</font></P><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY">那为什么不这样写程序,要用标号呢?不是增加疑惑吗?</P>
</FONT><P ALIGN="JUSTIFY"><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>如果这样写程序的话,在写程序时,我们就必须确定这张表格在</font><FONT SIZE=3>ROM</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的具体的位置,如果写完程序后,又想在这段程序前插入一段程序,那么这张表格的位置就又要变了,要改</FONT><FONT SIZE=3>ORG 100H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>这句话了,我们是经常需要修改程序的,那多麻烦,所以就用标号来替代,只要一编译程序,位置就自动发生变化,我们把这个麻烦事交给计算机��指</FONT><FONT SIZE=3>PC</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>机去做了。</font></P></DIR><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY">堆栈操作</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">PUSH direct</P>
<P ALIGN="JUSTIFY">POP	 direct</P>
</FONT><P ALIGN="JUSTIFY"><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>第一条指令称之为推入,就是将</font><FONT SIZE=3>direct</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的内容送入堆栈中,第二条指令称之为弹出,就是将堆栈中的内容送回到</FONT><FONT SIZE=3>direct</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中。推入指令的执行过程是,首先将</FONT><FONT SIZE=3>SP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值加</FONT><FONT SIZE=3>1</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,然后把</FONT><FONT SIZE=3>SP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值当作地址,将</FONT><FONT SIZE=3>direct</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值送进以</FONT><FONT SIZE=3>SP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值为地址的</FONT><FONT SIZE=3>RAM</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>单元中。例:</font></P>
<P ALIGN="JUSTIFY"><FONT SIZE=3>MOV	SP</font><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>#5FH</font></P><P ALIGN="JUSTIFY">
<FONT SIZE=3>MOV	A</font><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>#100</font></P><P ALIGN="JUSTIFY">
<FONT SIZE=3>MOV	B</font><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>#20</font></P><FONT SIZE=3>
<P ALIGN="JUSTIFY">PUSH	ACC</P>
<P ALIGN="JUSTIFY">PUSH	B</P>
</FONT><P ALIGN="JUSTIFY"><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>则执行第一条</font><FONT SIZE=3>PUSH ACC</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指令是这样的:将</FONT><FONT SIZE=3>SP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值加</FONT><FONT SIZE=3>1</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,即变为</FONT><FONT SIZE=3>60H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,然后将</FONT><FONT SIZE=3>A</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值送到</FONT><FONT SIZE=3>60H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>单元中,因此执行完本条指令后,</FONT><FONT SIZE=3> </FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>内存</FONT><FONT SIZE=3>60H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>单元的值就是</FONT><FONT SIZE=3>100</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,同样,执行</FONT><FONT SIZE=3>PUSH B</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>时,是将</FONT><FONT SIZE=3>SP+1</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,即变为</FONT><FONT SIZE=3>61H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,然后将</FONT><FONT SIZE=3>B</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值送入到</FONT><FONT SIZE=3>61H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>单元中,即执行完本条指令后,</FONT><FONT SIZE=3>61H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>单元中的值变为</FONT><FONT SIZE=3>20</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>。</font></P>
<P ALIGN="JUSTIFY"><FONT SIZE=3>POP</font><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指令的执行是这样的,首先将</FONT><FONT SIZE=3>SP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值作为地址,并将此地址中的数送到</FONT><FONT SIZE=3>POP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指令后面的那个</FONT><FONT SIZE=3>direct</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中,然后</FONT><FONT SIZE=3>SP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>减</FONT><FONT SIZE=3>1</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>。</font></P><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY">接上例:</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">POP	B</P>
<P ALIGN="JUSTIFY">POP	ACC</P>
</FONT><P ALIGN="JUSTIFY"><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>则执行过程是:将</font><FONT SIZE=3>SP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值(现在是</FONT><FONT SIZE=3>61H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>)作为地址,取</FONT><FONT SIZE=3>61H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>单元中的数值(现在是</FONT><FONT SIZE=3>20</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>),送到</FONT><FONT SIZE=3>B</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中,所以执行完本条指令后</FONT><FONT SIZE=3>B</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值是</FONT><FONT SIZE=3>20</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,然后将</FONT><FONT SIZE=3>SP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>减</FONT><FONT SIZE=3>1</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,因此本条指令执行完后,</FONT><FONT SIZE=3>SP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>的值变为</FONT><FONT SIZE=3>60H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,然后执行</FONT><FONT SIZE=3>POP ACC</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,将</FONT><FONT SIZE=3>SP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值(</FONT><FONT SIZE=3>60H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>)作为地址,从该地址中取数(现在是</FONT><FONT SIZE=3>100</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>),并送到</FONT><FONT SIZE=3>ACC</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中,所以执行完本条指令后,</FONT><FONT SIZE=3>ACC</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值是</FONT><FONT SIZE=3>100</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>。</font></P><P ALIGN="JUSTIFY">
<FONT FACE="宋体" LANG="ZH-CN" SIZE=3>这有什么意义呢?</font><FONT SIZE=3>ACC</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值本来就是</FONT><FONT SIZE=3>100</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>B</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值本来就是</FONT><FONT SIZE=3>20</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,是的,在本例中,的确没有意义,但在实际工作中,则在</FONT><FONT SIZE=3>PUSH B</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>后往往要执行其他指令,而且这些指令会把</FONT><FONT SIZE=3>A</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值,</FONT><FONT SIZE=3>B</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值改掉,所以在程序的结束,如果我们要把</FONT><FONT SIZE=3>A</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>和</FONT><FONT SIZE=3>B</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值恢复原值,那么这些指令就有意义了。</font></P><P ALIGN="JUSTIFY">
<FONT FACE="宋体" LANG="ZH-CN" SIZE=3>还有一个问题,如果我不用堆栈,比如说在</font><FONT SIZE=3>PUSH ACC</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指令处用</FONT><FONT SIZE=3>MOV 60H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>A</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,在</FONT><FONT SIZE=3>PUSH B</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>处用指令</FONT><FONT SIZE=3>MOV 61H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>B</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,然后用</FONT><FONT SIZE=3>MOV A</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>60H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>MOV B</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>61H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>来替代两条</FONT><FONT SIZE=3>POP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指令,不是也一样吗?是的,从结果上看是一样的,但是从过程看是不一样的,</FONT><FONT SIZE=3>PUSH</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>和</FONT><FONT SIZE=3>POP</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指令都是单字节,单周期指令,而</FONT><FONT SIZE=3>MOV</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指令则是双字节,双周期指令。更何况,堆栈的作用不止于此,所以一般的计算机上都设有堆栈,而我们在编写子程序,需要保存数据时,通常也不采用后面的方法,而是用堆栈的方法来实现。</font></P><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY">例:写出以下程序的运行结果</P>
</FONT><P ALIGN="JUSTIFY"><FONT SIZE=3>MOV	30H</font><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>#12</font></P><P ALIGN="JUSTIFY">
<FONT SIZE=3>MOV	31H</font><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>#23</font></P><FONT SIZE=3>
<P ALIGN="JUSTIFY">PUSH	30H</P>
<P ALIGN="JUSTIFY">PUSH	31H</P>
<P ALIGN="JUSTIFY">POP	30H</P>
<P ALIGN="JUSTIFY">POP	31H</P>
</FONT><P ALIGN="JUSTIFY"><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>结果是</font><FONT SIZE=3>30H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值变为</FONT><FONT SIZE=3>23</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,而</FONT><FONT SIZE=3>31H</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中的值则变为</FONT><FONT SIZE=3>12</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>。也就两者进行了数据交换。从这个例子可以看出:使用堆栈时,入栈的书写顺序和出栈的书写顺序必须相反,才能保证数据被送回原位,否则就要出错了。</font></P><P ALIGN="JUSTIFY">
<FONT FACE="宋体" LANG="ZH-CN" SIZE=3>作业:在</font><FONT SIZE=3>MCS51</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>下执行上面的例程,注意观察内存窗口和堆栈的变化。</font></P><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"></P></FONT></BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -