我们知道JZ是用来确定ZF标志位的值的。 ZF标志的值只能是1或0,使用JZ或JNZ时会发生跳转,这是不合理的。
程序在x86上编译,使用的芯片是8255。 程序的功能是使用b端口读取开关的状态,然后输出到a端口,其中a端口连接一个小灯泡,通过小灯泡来反映开关的状态。只有两个交换机连接到端口 B。某种状态。
代码和电路原理图如下
CODES SEGMENT
ASSUME CS:CODES
START:
mov al,10000010b ; 设置为控制字,A口方式0输出,B口方式0输入
mov dx,41bh;41bh为控制寄存器的地址
out dx,al;将控制字送入到控制寄存器中,完成芯片的初始化操作
L1: mov dx,419h;419h为B口的地址
in al,dx;从B口读入开关的状态
mov dx,418h;418h为A口的地址
out dx,al;将从B口读入的数据,输出到A口,控制灯的亮灭
cmp al,0H
JZ AB
cmp al,0FFH
JZ AB
jmp L1
AB:MOV AH,4CH
INT 21H
CODES ENDS
END START
...
L1: mov dx, 0419h
in al, dx
mov dx, 0418h
out dx, al
cmp al, 0H
JZ AB ; jumps if AL=0
cmp al, 0FFH
JZ AB ; jumps if AL=255
jmp L1
AB: MOV AH, 4CH
INT 21H
如果在端口 0419h 读取的字节为 0 或 255,则立即退出程序。
如果该字节是 [1,254],则留在 L1 循环中。
由于端口 b (0419h) 包含交换机的状态,那么也许 0 和 255 是可以从端口读取的唯一值?
提示:您应该使用
cmp al, 0FFH
助记符,而不是写 JZ AB
je
,它可以更好地表达这是比较相等性:
cmp al, 0H
je AB ; jumps if AL is equal to 0
cmp al, 0FFH
je AB ; jumps if AL is equal to 255
在
jz
指令之后使用 test
更为惯用。
5条说明:
cmp al, 0H
JZ AB ; jumps if AL=0
cmp al, 0FFH
JZ AB ; jumps if AL=255
jmp L1
AB:
可以写成:
add al, 1 ; 255 -> 0 and 0 -> 1
cmp al, 1
ja L1 ; Continue for all except the new 0 or 1
通过减少分支指令的数量,同时减少 4 个字节,可以实现更好的循环。
不太可能,但如果你的程序的退出代码需要是数字 {255,0},那么只需终止即可:
sub al, 1
mov ah, 4Ch
int 21h