测试状态位

时间:2011-08-29 22:48:06

标签: c x86 assembly

我一直在学习大会,我有一个问题。教科书提供了以下示例:

  

假设打印机数据端口被内存映射到地址0FFE0h   并且打印机状态端口是内存映射端口0FFE2h的第0位。   以下代码等待打印机准备好接受一个字节   然后它将数据写入L.O.斧头的字节   打印机端口:

0000:   mov     bx, [FFE2]
0003:   and     bx, 1
0006:   cmp     bx, 0
0009:   je      0000
000C:   mov     [FFE0], ax
         .       .
         .       .
         .       .
     

第一条指令在状态输入端口获取数据。该   第二条指令在逻辑上和该值一起清除位   1到15并将位0设置为当前状态   打印机端口。请注意,如果是,则在bx中产生零值   打印机正忙,如果是打印机,它会以bx为单位产生一个值   准备接受其他数据。第三条指令检查bx到   看它是否包含零(即打印机忙)。如果打印机是   忙,这个程序跳回到零位并重复这个   一遍又一遍地处理,直到打印机状态位为1。

为什么我们必须执行第二条指令and bx, 1?我们不能直接进入cmp bx, 0吗?

另外,请你澄清或重新说明“第二条指令是否合乎逻辑并将该值与1清除第1至第15位并将第0位设置为打印机端口的当前状态”?我不明白它现在意味着什么,因为英语不是我的第一语言。

谢谢你

4 个答案:

答案 0 :(得分:4)

状态字节的位字段可能包含其他位中的其他标志。在这种情况下,您只对位0(最低有效位)感兴趣,因此通过将值与1一起使用来忽略其余位,然后将值测试为0。

答案 1 :(得分:3)

假设内存地址0xFFE2包含一个8位的字节,例如:00010100。 只有最后一位包含有关打印机状态的信息。所有其他位对于此目的无关紧要。你将如何从这个字节中提取最后一位?

本书给出的解决方案(以及整体使用的解决方案)是使用bitwise and operator将无关紧要的所有位清零:

      00010100  # content of the memory cell (0x14)
and   00000001  # 0x1
---------------
      00000000

...或...

      00010101  # content of the memory cell (0x15)
and   00000001  # 0x1
---------------
      00000001

你知道这是怎么回事,不是吗?通过将操作结果与0进行比较,如果最后一位为0,则可以得到明确的答案,因此打印机是否准备就绪。因此,在这种情况下,and运算符只是从字节中提取单个位的一种方法,仅此而已。

答案 2 :(得分:1)

因为问题所述,“打印机状态端口为零”。如果您没有使用该AND指令清除其他位,即使感兴趣的位为零,这些也可能导致您不进行跳转。

答案 3 :(得分:0)

既然你是学生,你可能需要的不仅仅是一个简单的答案:

BX是一个16位寄存器,只有第一位(位0)才有意义。 例如,对bx使用值10101111 00101000(AF28h)。 即使位0的值为零, cmp bx,0 也会返回false,因为cmp会比较整个寄存器的值,而不仅仅是位0。

换句话说, cmp bx,0 = false,因为AF28h<> 0

如果第一位为0,则行和bx,1 将bx的值更改为0;如果第一位为1,则将的值更改为

在我的例子中,和bx,1 设置bx = 0,因为位0的值为零

enter image description here