我一直在学习大会,我有一个问题。教科书提供了以下示例:
假设打印机数据端口被内存映射到地址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位设置为打印机端口的当前状态”?我不明白它现在意味着什么,因为英语不是我的第一语言。
谢谢你
答案 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的值为零