在我的问题中:
AX= 16 位累加器寄存器。
AL=AX 寄存器的 8 个低位。DATA8= 最多 8 位的立即数。以十为底,它可以在 0-255 之间,如果这个数字不重要。我们假设这个数字是无符号的。
DATA16= 一个由 16 位组成的十六进制数。
那么,回到问题:
在 8086 Instructor set 中,ADD AX, DATA16需要 4 个时钟周期,它的目标代码是05 YYYY。
在05 YYYY 中, 05 是 1 字节, YY 也是 1 字节,因此整个目标代码是 3 字节大小。ADD AL, DATA8需要 4 个时钟周期,ADD AX,DATA16但ADD AX, DATA8目标代码是04 YY
如果我写ADD AX, 10H ,我的源操作数(操作数 2)是十六进制 10,所以它是 8 位。AX由AH和AL组成。AH 是 AX 的最高有效位的 8 位,AL 是相反的 8 位。但是在我们的代码中ADD AX, 10H ,我们添加了 8 位数字的 AX 并更新了 AX。根据AX由AH和AL组成,实际上,我们在这段代码中是用AL和10H求和的,所以我们的代码大小是04 YY的2字节还是符合8086指令集,我们是否遵守严格的规则而不是不是这样想的,我们在AX, DATA8 中接受,我们的第一个操作数是 AX 但第二个操作数是 DATA8 并且指令集没有这样的助记符,所以我们认为它一定是AL, DATA8?
原谅我,这个问题我拖得太久了。
在ADD AX, imm指令 opcode 中05h,立即数始终编码为两个字节(16 位),即使它恰好小于 255。您ADD AX, 10h的编码为05 10 00, 三个字节。
这是它可以工作的唯一方法。CPU 只看到字节;它无法知道是否10表示一个字节的立即数,下一个字节是否10是下一条指令的一部分,或者是否是两字节操作数的低字节。换句话说,如何知道05 10 90是ADD AX, 10h ; NOP还是ADD AX, 9010h?解决这个问题的唯一方法是声明操作码 05总是采用两个字节的立即数,如果所需的值适合一个字节,那么最高有效字节就简单地指定为零。
请注意,还有另一种形式的ADDopcode 83h,它采用一个字节(8 位)立即数并将其符号扩展为 16 位。由于您的立即数10h确实适合有符号的 8 位数字,因此可以使用此表格。然而,由于它的目标是一个通用的 r/m 操作数,它需要一个额外的字节来指定寄存器,并将编码为83 c0 10,仍然是三个字节。请注意,如果您想添加无符号的 8 位数量a0h,这将不起作用,因为它将被符号扩展为ffa0h.
ADD AL, 10h04 10正如您所说的那样编码为两个字节,但正如 Jester 指出的那样,这与ADD AX, 10h您可以从低字节到高字节进行进位不同。如果AX包含00f3h,ADD AX, 10h则将导致AX = 0103h并清除进位标志,而ADD AL, 10h将导致AX = 0003h并设置进位标志。