Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly A86-定义与正向引用冲突_Assembly_X86 16_Forward Reference_A86 - Fatal编程技术网

Assembly A86-定义与正向引用冲突

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:不允许字节/单

我正在尝试使用A86为8086汇编一些代码。我把问题缩小到4行代码

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