您遇到的问题源于 A86 是单通道汇编程序这一事实。当您在定义它们之前使用testz 和second 之类的符号时,A86 必须猜测它们是什么。它假设它们将是立即值,但后来它发现它们实际上是标签。多阶段汇编器可能会返回并更改其先前做出的决定,但 A86 不会这样做。它只是抛出一个错误(#16)。这就是错误出现在定义附近的源文件中的原因:这就是 A86 发现问题时所在的位置。
您可以使用offset、d、w 等指令明确地告诉 A86 你想让它做什么,这样它就不必猜测了。
A86 manual 解释说:“重要提示:您必须了解标签和变量之间的区别,因为如果混淆它们,您可能会生成与预期不同的指令。例如,如果您声明 XXX : DW ?, XXX 后面的冒号表示 XXX 是一个标号;指令 MOV SI,XXX 将 XXX 的立即常数地址移动到 SI 寄存器中。 XXX 是一个字变量;同样的指令 MOV SI,XXX 现在做了一些不同的事情:它将内存字 XXX 的运行时值加载到 SI 寄存器中。您可以在任何用法中使用立即数覆盖符号的定义-值运算符 OFFSET 或内存变量运算符 B、W、D、Q 或 T。因此,无论 XXX 如何声明,MOV SI,OFFSET XXX 加载指向 XXX 的立即值;MOV SI,XXX W 加载字- XXX 处的变量,无论 XXX 是如何声明的。”
这应该回答您的第二个问题:当 A86 看到 add bl, [second] 时,它假定 second 将是一个立即字节大小的操作数,因为 bl 是一个字节大小的寄存器。
您的下一行 mov bx, second 期望 second 是立即字大小的操作数,但 A86 已经注意到 second 将是一个字节,因此您会收到错误 #13。
你可以通过这样做得到你想要的:
add bl, second b ; add the byte at memory location ds:second to bl
mov bx, offset second
一般来说,如果您在使用符号之前定义它们,这些问题就会消失。例如,这将起作用:
name example1 ; good code
code segment
org 0100h
main: ; - MACHINE CODE
mov bx, main ; BB0001 - put 0100h in bx
mov bx, offset main ; BB0001 - put 0100h in bx
; ^ offset directive not needed here
; A86 already knows what to do
mov bx, [main] ; 8B1E0001 - put 00BBh in bx
; ^ brackets work fine to dereference main here
mov bx, main w ; 8B1E0001 - put 00BBh in bx
; ^ w does the same thing as brackets
org 0150h
goodbye:
int 020h
code ends
end main
但这不起作用:
name example2 ; will not assemble
code segment
org 0100h
main: ; - MACHINE CODE
mov bx, goodbye ; BB5001 - put 0150h in bx
; ^ A86 assumes goodbye is an immediate value. This assumption
; turns out to be a good one, so this line works OK
mov bx, offset goodbye; BB5001 - put 0150h in bx
; ^ offset directive tells A86 that goodbye will be an immediate
; value. You can skip it, since A86 assumes that anyway
mov bx, [goodbye] ; this line is the culprit!
; ^ A86 doesn't know what to do about these brackets
mov bx, goodbye w ; 8B1E5001 - put 20CDh (`int 020h`) in bx
; ^ w directive tells A86 that goodbye will be a word
; variable
org 0150h
goodbye: ; label goodbye not defined until way down here!
int 020h
code ends
end main