This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

no message about A14 error generated

hi,

next example is compiled without errors but produces wrong results due debug.

;------------------------------------------------------------
; Test program about bug of relocatable calculations
;------------------------------------------------------------
; allocate buffer in XDATA
?XD?BUFFER	SEGMENT	XDATA
		RSEG	?XD?BUFFER
BUFFER:		DS	512	; here may be any number

;------------------------------------------------------------
; Main program
?PR?MAIN	SEGMENT CODE
		RSEG	?PR?MAIN
; load high byte of the buffer address +1 into accumulator
	MOV	A,#(HIGH(BUFFER)+1)
; !!! accumulator contains high byte without +1 !!!

	MOV	A,#(HIGH(BUFFER+256*1))
; here we obtain the correct result

	JMP	$

	END

I know source of the problem but I have no idea why no error about "INVALID RELOCATABLE EXPRESSION" is generated?

Thanks,
Oleg

Parents
  • Hans-Bernhard Broeker,

    To get what was apparently intended, you would have had to write

    (HIGH BUFF) + 1
    


    I have tested your suggestion and
    	MOV	A,#(HIGH BUFFER) + 1
    
    still gets wrong result. For example, ?XD?BUFFER is located at 0x1100 then both
    	MOV	A,#(HIGH(BUFFER)+1)
    	MOV	A,#(HIGH BUFFER) + 1
    
    gives Acc to be loaded with 0x11. And this is wrong result witout a warning/error message.
    The problem I see is that linker/locator cannot process relocatable expression like (HIGH(BUFFER)+1) correctly.

    See, there is no problem if I define XDATA segment like
    ?XD?BUFFER	SEGMENT	XDATA AT 0x1100
    
    In this case it works right: both your suggestion and my MOV A,#(HIGH(BUFFER)+1) work correct and load Acc with 0x12 due I use abasolute located segment.
    But in case of relocable segments linker accepts the expression but does calculate it wrong. I have no idea why - either there is a bug into OMF processor or linker cannot process such expression because assembler passes wrong fixup records to the OBJ file.

    This message is related to the http://www.keil.com/forum/docs/thread5744.asp thread (read the bottom there). There Jon Ward explains why
    	MOV	A,#(LOW(XBUF) + 1)  ; line 1
    	MOV	A,#(LOW(XBUF) OR 1) ; line 2
    
    line 1 works but line 2 is INVALID RELOCATABLE EXPRESSION. Now it appears that even the first line is parsed, it produces wrong results.

    Regards,
    Oleg

Reply
  • Hans-Bernhard Broeker,

    To get what was apparently intended, you would have had to write

    (HIGH BUFF) + 1
    


    I have tested your suggestion and
    	MOV	A,#(HIGH BUFFER) + 1
    
    still gets wrong result. For example, ?XD?BUFFER is located at 0x1100 then both
    	MOV	A,#(HIGH(BUFFER)+1)
    	MOV	A,#(HIGH BUFFER) + 1
    
    gives Acc to be loaded with 0x11. And this is wrong result witout a warning/error message.
    The problem I see is that linker/locator cannot process relocatable expression like (HIGH(BUFFER)+1) correctly.

    See, there is no problem if I define XDATA segment like
    ?XD?BUFFER	SEGMENT	XDATA AT 0x1100
    
    In this case it works right: both your suggestion and my MOV A,#(HIGH(BUFFER)+1) work correct and load Acc with 0x12 due I use abasolute located segment.
    But in case of relocable segments linker accepts the expression but does calculate it wrong. I have no idea why - either there is a bug into OMF processor or linker cannot process such expression because assembler passes wrong fixup records to the OBJ file.

    This message is related to the http://www.keil.com/forum/docs/thread5744.asp thread (read the bottom there). There Jon Ward explains why
    	MOV	A,#(LOW(XBUF) + 1)  ; line 1
    	MOV	A,#(LOW(XBUF) OR 1) ; line 2
    
    line 1 works but line 2 is INVALID RELOCATABLE EXPRESSION. Now it appears that even the first line is parsed, it produces wrong results.

    Regards,
    Oleg

Children
  • oops,

    the things are even worse:

    	MOV	A,#(LOW(BUFFER) + 1)  ; line 1
    	MOV	A,#(HIGH(BUFFER) + 1)  ; line 2
    

    line 1 works correct and line 2 produces wrong result.
    Now I do understand nothing. Does linker not know about HIGH, but about LOW only?

    Thanks,
    Oleg

  • line 1 works correct

    Are you sure? I ask because it looks rather similar to the 3rd example under "Invalid form of simple relocatable expressions" in the manual section "Extended Relocatable Expressions" (p.97), where it says:

    LOW may be applied only to the final relocatable expression

    That seems to say that you actually have to write an equivalent of

    HIGH(BUFF+0x100)

    To debug this further would need detailed information about .obj file contents as used by Keil.

  • set bufoff BUFF+whatever

    a,#HIGH bufoff

    will work

  • It is hard to say exactly but for lines:

    	MOV	A,#(LOW(BUFFER)+1)
    	MOV	A,#(HIGH(BUFFER)+1)
    	JMP	$
    
    final code is:
        11:         MOV     A,#(LOW(BUFFER)+1)
    C:0x0000    7401     MOV      A,#0x01
        12:         MOV     A,#(HIGH(BUFFER)+1)
        13:
    C:0x0002    7400     MOV      A,#0x00
        14:         JMP     $
    C:0x0004    80FE     SJMP     C:0004
    
    Map file shows that BUFFER is located at 0x0000:
    X:0000H SYMBOL BUFFER
    
    So I assumed that LOW works but HIGH does not.

    Regards,
    Oleg

  • Unfortunately, HIGH and LOW are not like functions you can use in your assembler code.

    They are instead like expression-wide modifiers that change the byte the assembler/linker view for purposes of instruction construction.

    For example, all of the following expressions using HIGH are evaluated to the same result:

    high buffer + 1
    1 + high buffer
    high(buffer) + 1
    

    The reason is that when the expression is calculated, the HIGH keyword simply sets flag. The expression is calculated (ignoring the HIGH keyword). And, HIGH is applied to the result. The same is true for the LOW and other byte-specific keywords.

    So, if you want to adjust the high byte, you must do something like...

    high buffer+256
    

    Jon