8086装配相关的麻烦

时间:2017-05-17 14:21:08

标签: assembly x86-16

这可能是非常基本的,但我无法理解它。

我正在使用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有效地做了什么?它是否在DX中存储PORT_B的地址?为什么它在AL中输入B的高字节,然后将AL移到AH,而不是简单地将其写为IN AH, DX

对于端口A和B的地址,“0008h”和“000Ah”的明智选择是什么?我以前只使用8085组装,如果之前我选择了0008h(0000 0000 0000 1000b),那么我就不会选择000A(0000 0000 0000 1010b),因为A3位重叠(例如,I' d选择0001h(... 0001b)和0002h(.... 0010b),以便没有位重叠)。

3 个答案:

答案 0 :(得分:3)

  

我使用8255的A和B端口输入单词

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

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

  • 当我们使用in al, dx
  • 时的一个字节
  • 我们使用in ax, dx
  • 时的一句话
  • 当我们使用in eax, dx
  • 时的dword

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

wallyk对您提供的代码做了很好的评论。所以我想你明白为什么以及如何。

我想补充的是,此代码可以进行优化。

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

鉴于上述端口地址,可以更直接地完成阅读该单词的任务。对于适合单个字节的I / O地址,从0000h到00FFh,根本不需要使用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个字节的短版本(编程只是喜欢空间保护)是:

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

答案 1 :(得分:2)

缺少的评论将是这样的

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
  

为什么它在AL输入B的高字节,然后将AL移到AH,而不是简单地将其写为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指令集看起来正交,但是充满了半惊人的限制和限制。

答案 2 :(得分:0)

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