Question

I'm trying to use A86 to assemble some code for 8086. I narrowed my problem down to 4 lines of code.

MOV BX, testz
ADD AL, [testz]

INT 20h
testz:
~     ^
#ERROR 16: Definition Conflicts With Forward Reference                    @@@@#
db ?

What do you think is wrong with this code? I am moving the address itself to BX register and adding the byte-value in the testz address to AL.

In a bigger program I also get #ERROR 13: Byte/Word Combination Not Allowed.

But label is a word where [label] is a byte. Why can't my compiler differentiate between those?

ADD BL, [second]
MOV BX, second
~             ^
#ERROR 13: Byte/Word Combination Not Allowed   
second:
~      ^
#ERROR 16: Definition Conflicts With Forward Reference                    @@@@#
db ?

Because I can't see any Byte/Word conflict.


My compiler interprets offset testz and testz equally. I looked at the bytecodes and couldn't see any difference.

MOV BX, testz
ADD AL, [BX]

The code above works, but is there any other way that I can do this in one line like

ADD AL, [testz]

Whenever I put a label name in [], it is just not acceptable according to my compiler a86. But I feel they are allowed in the language.

Was it helpful?

Solution

I suspect you want MOV BX, offset testz. It appears that your assembler interprets [testz] and testz to mean the same thing.

You might confirm this by trying instead the notionally equivalent LEA BX, testz

EDIT: (from http://www.csn.ul.ie/~darkstar/assembler/manual/a14.txt):

ERROR 16: Definition Conflicts With Forward Reference

   This error occurs when the assembler has previously guessed
   the type of a forward-referenced symbol in order to determine
   what kind of instruction to generate, and the guess turned out
   to be wrong.  The error is reported at the time the symbol is
   defined.  For example, when A86 sees MOV AX,FOO, it will
   assume FOO is an immediate value.  This error is reported if
   FOO turns out to be a word variable: FOO DW 0.  You need to
   search backwards from the error message, to references of FOO,
   and specify the type you intend to be used: MOV AX,FOO W.  If
   you really did intend to load the offset of FOO and not the
   memory contents, you can code MOV AX,OFFSET FOO to make the
   error message go away.

OTHER TIPS

The problem you are running into stems from the fact that A86 is a single pass assembler. When you use symbols like testz and second before defining them A86 has to guess what they are. It assumes that they will be immediate values, but later on it discovers that they're actually labels. A multi-phase assembler might go back and change the decision it made earlier, but A86 doesn't do that. It simply barfs forth an error (#16). This is why the error appears in the source file near the definition: that's where A86 was when it discovered the problem.

You can use the directives offset, d, w, and so on to tell A86 explicitly what you want it to do, so it won't have to make guesses.

The A86 manual explains: "IMPORTANT: you must understand the distinction between a label and a variable, because you may generate a different instruction than you intended if you confuse them. For example, if you declare XXX: DW ?, the colon following the XXX means that XXX is a label; the instruction MOV SI,XXX moves the immediate constant address of XXX into the SI register. On the other hand, if you declare XXX DW ? with no colon, then XXX is a word variable; the same instruction MOV SI,XXX now does something different: it loads the run-time value of the memory word XXX into the SI register. You can override the definition of a symbol in any usage with the immediate-value operator OFFSET or the memory-variable operators B,W,D,Q, or T. Thus, MOV SI,OFFSET XXX loads the immediate value pointing to XXX no matter how XXX was declared; MOV SI,XXX W loads the word-variable at XXX no matter how XXX was declared."

This should answer your second question: When A86 sees add bl, [second] it assumes that second will be an immediate byte sized operand since bl is a byte sized register.

Your next line mov bx, second expects second to be an immediate word sized operand, but A86 has already made a note that second will be a byte, so you get error #13.

You can get what you want by doing this instead:

add bl, second b        ; add the byte at memory location ds:second to bl
mov bx, offset second

Generally, these problems will disappear if you define your symbols before using them. For example, this will work:

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

but this will not work:

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

The DOS Manual instructs for a pointer for a handler for such :

mov ax, word ptr es:[bx],BBBB

to where BBBB is the base

also is the reference to the base for the segment-the same after pushing cx[i think-I cant remember]

to which the same is as above except at BBBB is SSSS for segement

Now I wrote a handler when my mouse stopped functionign becasue of a bad crash and I used this word ptr as a byte instead of a word and it appears to work as i never made an actual word pointer but just used 'word ptr' in teh program along with a backwards binary conversion of the byte into hex [A6 backwards is 65].

Also is the error I found int eh DOS amnual for making an INT call [not as in debug assembly or programmign assembly by calling int ## but actually making a direct call to the 8080 and to which the fact of this is that it is not an interrupt call but an IRQ call.The instruction code is incorrect-specifically in the presentation. Also on the Intel es:[bx] does not work-must use es[bx]

Also ine xtension-wheres my head at---to answer your question you are making a reference to an 8 bit register and then the 16 bit register-to whcih you are instructing ADD bl and then change bx after the add operand.This is your error #13.

What you must do is assure that bl is compatable with BX prior to-or such you will get a no forward reference error to which basicially what this is.The ADD instruction automatically protects the BX from being amnipulated until tis calculation request or command request is fully complete unless it is undertaken as an IRQ request to which it may be suspended with sti and cli to which in between is a reference for changing the page table or the reference table.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top