我目前正在学习计算机架构课程,其中使用的文本之一是 James W. Coffron 撰写的“Programming the 8086/8088 First Edition”(亚马逊对此的评论称其“充满了语法和技术错误”) .
我不确定我是否愚蠢,但下面的摘录似乎存在矛盾:
FIGURE 3.10:
##########
REG bits | 16-BIT REGISTER | 8-BIT REGISTER
000 | AX | AL
001 | CX | CL
010 | OX | OL
011 | BX | BL
100 | SP | AH
101 | BP | CH
110 | SI | OH
111 | 01 | BH
在此示例中,我们将从内存中移动数据,或者将寄存器移入或移出寄存器。我们将使用像 MOV AX,BX 这样的指令。该指令有 2 个字节,因为没有要添加的内存地址。字节将如图 3.11 所示(100010DW MOD REG R/M)。
从图 3.11 中我们可以看到,第一个字节的低两位为 DW,其中 W 代表字或字节(如前所示)。 D 表示数据是否存放在 MOD 和 R/M 字段指定的操作数中,D=0,或者是否存放在 REG 字段指定的寄存器中,D=1。
图 3.12 显示了 MOD 和 R/M 分配。请注意,在 MOD 描述中,如果值为 11,则 R/M 字段采用寄存器格式进行编码。这种格式如图 3.10 所示。
对于该指令,我们希望将数据存储在 AX 寄存器中。因此,D 位将是逻辑 O。
^ AX 不是在 REG 列表中吗?他们在 REG 字段中存储时不是说 D=1 吗?
这意味着数据必须存储在MOD和R/M字段指定的位置。因此,MOD 将等于 11。R/M 字段将等于 000,表明 AX 寄存器是数据的目的地。数据第二个字节的 REG 字段将等于 all,从而表明 BX 寄存器是要使用的源寄存器(该值来自图 3.10)。该指令的完整第二个数据字节将为 11 011 000 或 D8。因此,指令 MOV AX,BX 的目标代码为 89D8。
^ 使用 emu8086 事实上,我已经确认 MOV AX,BX 的目标代码是 8BC3,并将其转换为二进制,D 位确实设置为 1。基于此,我确实认为教科书中有错误,这让我很生气,因为它浪费了我很多时间。
FIGURE 3.12:
BASE AND INDEX REGISTER SPECIFIED BY R/M FOR OPERANDS IN MEMORY (MOD ≠ 11)
##########
R/M FIELD | BASE REGISTER | INDEX REGISTER
----------
000 | BX | SI
001 | BX | DI
010 | BP | SI
011 | BP | 01
100 | NONE | SI
101 | NONE | 01
110 | BP | NONE
111 | BX | NONE
##########
MOD | DISPLACEMENT | COMMENT
----------
00 | ZERO
01 | 8·BIT CONTENTS OF NEXT BYTE OF INSTRUCTION SIGN EXTENDED TO 16 BITS | INSTRUCTION CONTAINS AN ADDITIONAL BYTE
10 | 16·BIT CONTENTS OF NEXT TWO BYTES OF INSTRUCTION | INSTRUCTION CONTAINS TWO ADDITIONAL BYTES
11 | R/M REGISTER
##########
IF MOD=00 AND R/M=110, THEN:
1. THE ABOVE DOES NOT APPLY
2. THE INSTRUCTION CONTAINS TWO ADDITIONAL BYTES
3. THE OFFSET ADDRESS IS CONTAINED IN THOSE BYTES
请注意,
mov ax, bx
有两种编码。两者都正确。
本书使用
mov r/m16, r16
,操作码89
。在这种情况下,目的地是 r/m16
,因此是 D=0
、r/m=ax
和 reg=bx
。机器代码是 89 D8
.
使用 emu8086 发现的是指令
mov r16, r/m16
,操作码8B
。这里的目的地是 r16
,因此 D=1
、r/m=bx
和 reg=ax
机器代码是 8B C3
。