Assembly A86-定义与正向引用冲突
我正在尝试使用A86为8086汇编一些代码。我把问题缩小到4行代码Assembly A86-定义与正向引用冲突,assembly,x86-16,forward-reference,a86,Assembly,X86 16,Forward Reference,A86,我正在尝试使用A86为8086汇编一些代码。我把问题缩小到4行代码 MOV BX, testz ADD AL, [testz] INT 20h testz: ~ ^ #ERROR 16: Definition Conflicts With Forward Reference @@@@# db ? 你认为这个代码有什么问题?我将地址本身移动到BX寄存器,并将testz地址中的字节值添加到AL 在一个更大的程序中,我也得到了#错误13:不允许字节/单
MOV BX, testz
ADD AL, [testz]
INT 20h
testz:
~ ^
#ERROR 16: Definition Conflicts With Forward Reference @@@@#
db ?
你认为这个代码有什么问题?我将地址本身移动到BX寄存器,并将testz地址中的字节值添加到AL
在一个更大的程序中,我也得到了#错误13:不允许字节/单词组合
但是label
是一个单词,其中[label]
是一个字节。为什么我的编译器不能区分这些
ADD BL, [second]
MOV BX, second
~ ^
#ERROR 13: Byte/Word Combination Not Allowed
second:
~ ^
#ERROR 16: Definition Conflicts With Forward Reference @@@@#
db ?
因为我看不到任何字节/字冲突
我的编译器同等地解释偏移量testz和testz。 我看了看字节码,看不出有什么区别
MOV BX, testz
ADD AL, [BX]
上面的代码可以工作,但是有没有其他方法可以像这样在一行代码中完成
ADD AL, [testz]
根据我的编译器a86,每当我在[]中放置标签名时,它都是不可接受的。但是我觉得它们在语言中是允许的。我想你想要
MOV BX,offset testz
。似乎您的汇编器将[testz]
和testz
解释为相同的意思
您可以通过尝试概念上等效的LEA BX,testz
编辑:(来自):
DOS手册为处理程序指示指针,用于: mov ax,单词ptr es:[bx],bbbbbb 到BBBB为基础的位置 推cx之后,段的基准参考是否相同[我想-我不记得了] 除BBBB处为分段SSS外,与上述相同 现在我写了一个处理程序,当我的鼠标因为一次严重的崩溃而停止运行时,我使用这个单词ptr作为一个字节,而不是一个单词,它似乎可以工作,因为我从来没有做过一个实际的单词指针,只是在程序中使用了“单词ptr”,并将字节向后二进制转换为十六进制[A6向后是65] 还有一个错误是我发现int eh DOS amnual发出int调用[不像在调试程序集或programmign assembly中那样通过调用int#####,而是直接调用8080,事实上这不是中断调用而是IRQ调用。在演示文稿中,指令代码是不正确的。 同样在英特尔es上:[bx]不起作用,必须使用es[bx] 另外,我的头在哪里?为了回答你的问题,你引用了一个8位寄存器,然后是16位寄存器,这是你的错误#13
您必须做的是确保bl在之前与BX兼容,否则您将得到一个无前向参考错误,基本上就是这个错误。ADD指令自动保护BX,直到计算请求或命令请求完全完成为止,除非它作为IRQ请求进行,否则它可能使用sti和cli挂起,两者之间是更改页表或引用表的引用。您遇到的问题源于A86是单程汇编程序。当您在定义它们之前使用
testz
和second
等符号时,A86必须猜测它们是什么。它假定首先,它们将是立即值,但稍后它发现它们实际上是标签。多阶段汇编程序可能会返回并更改其先前做出的决定,但A86不会这样做。它只是发出一个错误(#16)。这就是为什么该错误出现在定义附近的源文件中:这就是A86发现问题时的位置
您可以使用指令offset
、d
、w
,等等明确地告诉A86您希望它做什么,这样它就不必猜测了
A86说明:"重要提示:您必须理解标签和变量之间的区别,因为如果混淆它们,您可能会生成与预期不同的指令。例如,如果您声明XXX:DW?,则XXX后面的冒号表示XXX是标签;指令MOV SI,XXX将XXX的立即常量地址移动到SI区域中另一方面,如果您声明XXX DW?不带冒号,那么XXX是一个字变量;同一条指令MOV SI,XXX现在做了一些不同的事情:它将内存字XXX的运行时值加载到SI寄存器中。您可以使用立即值运算符OFFSET或内存变量o覆盖任何用法中的符号定义运算符B、W、D、Q或T。因此,MOV SI,OFFSET XXX加载指向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
啊!例如,这可以添加AL,testz B。所以当我编写[testz]我实际上是指testz B。但我的语法和假设是错误的吗?还是我的编译器选择了那样实现它们?我接触A86已经……几十年了?……8086汇编程序语法的事实标准是MASM的语法。但是A86做的事情有点不同。感觉A86是在尝试进行单通道汇编布莱,虽然MASM使用了多路径方法。但我不记得很清楚。所以A86基本上是所有可能的世界中最糟糕的,其中
mov ax,label
的含义取决于标签是代码还是数据标签?我想MASM是
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