为什么这段代码没有以更简单的方式编写?

电器工程 微处理器 集会 8051
2022-01-17 20:10:48

我在研究汇编语言时遇到了一个问题。这是问题:

假设位 P2.2 用于控制室外灯,位 P2.5 用于控制建筑物内的灯。展示如何打开外部灯并关闭内部灯。

给出的解决方案:

SETB C            ; CY = 1
ORL C, P2.2       ; CY = P2.2 ORed w/ CY
MOV P2.2, C       ; turn it on if not on
CLR C             ; CY = 0
ANL C, P2.5       ; CY = P2.5 ANDed w/P2.5
MOV P2.5,C        ; turn it off if not off

我只是觉得它会做同样的编码工作:

SETB P2.2
CLR P2.5

那有什么问题?

4个回答

你是对的,你显示的代码看起来很愚蠢。也许运行它的任何机器都不能立即操作来设置 I/O 端口上的位,这就是为什么像 SETB P2.2 这样的东西是不可能的。

仍然将 CY 位设置为 1,然后将任何东西或任何东西都放入其中是很愚蠢的。将 CY 位设置为 0 也是如此,然后将某些内容与其中相结合。很明显,CY 位可以直接复制到 I/O 引脚位,因为代码就是这样做的。最多应该是 4 条指令,当然不是 6 条。

该代码几乎肯定适用于使用 8051 指令集的处理器。在该处理器上,您提供的代码变体将具有与原始代码相同的效果,只是它运行得更快。在设置进位时执行“ORL C,P2.2”除了浪费一些周期外没有明显的影响(如果我没记错的话,在 8051 上的两个 CPU 周期总共 24 个时钟周期;在其他一些变体上可能有不同的数字) . 与清除进位时执行“ANL C,P2.5”类似。尽管可能存在某些类型的处理器,其中读取某些 I/O 位置的请求会产生一些可观察到的效果,但我认为任何 8051 型处理器对于任何可位寻址的 I/O 位置都没有这样的行为,很多P2 的位更少。

也许代码的目的是演示ORL C,bitandANL C,bit指令,但这似乎是一个奇怪的示例来演示它们。

给出的汇编代码可能是编译器生成的。它是以下 C 语句的未优化版本,其中P2_2P2_5是位可寻址对象:

P2_2 |= 1;
P2_5 &= 0;

这似乎等同于P2_2 = 1;and P2_5 = 0;,但如果位寻址寄存器是易失性对象,则不是。对 volatile 对象的读-修改-写操作必须按该顺序执行读和写。这确保了实际发生读取或写入寄存器的任何副作用。

尽管我知道没有具有副作用的 8051 位可寻址寄存器,但编译器不能假设不存在或永远不会存在。

这些之间的真正区别可能是微妙的。

在您的简化答案中,逻辑是读取端口,设置或清除位值,然后将其写回端口。注意整个端口可以在这里重写。

另一方面,该解决方案使用 MOV 位指令,该指令可能以完全不同的方式运行。

如果不详细介绍此处使用的特定部分的细节,就很难确定是否存在差异,或者是否重要。

或者它可能只是教练决定让你思考......这毕竟是......他真正的工作。