8086组装相关故障

8086 assembly related troubles

这可能很基础,但我真的看不懂。

我正在使用 8255 的 A 和 B 端口输入一个字。我有类似的东西:

PORT_A EQU 0008h // inputs low byte
PORT_B EQU 000Ah // inputs high byte

稍后在代码段中,我有一个部分执行此操作:

MOV DX, PORT_B
IN AL, DX
MOV AH, AL
MOV DX, PORT_A
IN AL, DX
MOV DX, AX

我有几个问题。 MOV DX, PORT_B 有效地做什么?它是否将 PORT_B 的地址存储在 DX 中?为什么把B的高字节输入AL,然后把AL移到AH,而不是简单写成IN AH, DX?

如何才能使“0008h”和“000Ah”成为端口 A 和 B 的地址的明智选择?我只使用过 8085 汇编,如果我之前选择 0008h (0000 0000 0000 1000b),我不会选择 000A (0000 0000 0000 1010b),因为 A3 位重叠(例如,我' d 选择 0001h (... 0001b) 和 0002h (.... 0010b),这样就没有位重叠)。

MOV DX PORT_B 将常量的值(EQU 创建一个常量)PORT_B 移动到 16 位寄存器 DX 中。因此,AX 获得的值为 000Ah(以 10 为基数的 10)。 IN 在低位字节完成,因为 000Ah 足够小,可以放入 AX 的 8 位部分。 AH 得到 AL 的值,这样在 PORT_A 放入 AL 的同时,可以保留 PORT_B 的值。

缺少的评论是这样的

MOV  DX, PORT_B     ; set up address of port B
IN   AL, DX         ; read high byte from port B
MOV  AH, AL         ; save result from port B as most significant byte

MOV  DX, PORT_A     ; set up address of port A
IN   AL, DX         ; read low byte from port A
MOV  DX, AX         ; DX = 16 bit result

Why does it input B's high byte in AL, and then moving AL to AH, instead of simple writing it down as IN AH, DX?

因为唯一的指令选择是

in   al, dx        ; read 8 bits
in   ax, dx        ; read 16 bits
in   eax, dx       ; (32 bit mode only, i.e. 80386+) read 32 bits

没有in ah, dx。 x86 指令集 看起来 正交,但充满了像这样的半令人惊讶的限制和限制。

I'm using 8255's A and B ports to input a word

然后您将从 8255 的 A 端口获取字的低字节,从 8255 的 B 端口获取字的高字节。

要从任何端口获取任何内容,我们首先将 I/O 端口的地址移动到 DX 寄存器中。然后我们使用 in 指令来实际获取内容。这可以是:

  • 当我们使用in al, dx
  • 时一个字节
  • 我们用in ax, dx
  • 时的一个词
  • 我们使用 in eax, dx
  • 时的双字

这些是来自 I/O 个端口的 in 的唯一可能目的地。 (AH 不是一个选项!)

wallyk 很好地评论了您提供的代码。所以我认为您已经了解了原因和方式。


我想补充的是这段代码可以优化。

PORT_A EQU 0008h // inputs low byte
PORT_B EQU 000Ah // inputs high byte

鉴于以上端口地址,还有更直接的方法可以完成读字任务。对于从 0000h 到 00FFh 适合单个字节的 I/O 地址,根本不需要使用 DX 寄存器。这些端口地址可以 in 指令本身 .

中指定

这提供了相当小的代码大小:

IN   AL, PORT_B   ; Fetch high byte from port B
MOV  DH, AL       ; Becomes high byte of end result in DX
IN   AL, PORT_A   ; Fetch low byte from port A
MOV  DL, AL       ; Becomes low byte of end result in DX

还有 1 个字节的更短版本( 编程只是喜欢 space 保护)是:

IN   AL, PORT_B   ; Fetch high byte from port B
MOV  AH, AL       ; Store in AH for now
IN   AL, PORT_A   ; Fetch low byte from port A
XCHG DX, AX       ; Transfer AX to end result in DX