assemblyz80

Assembly's numeric variable modifies the previous one


While learning Z80 assembly I've go a strange behavior that after declaring 2 numeric variables the value of the first one gets a totally different value.

Example:

    org 32768

    ld bc,(score1)
    call 6683
    ret

score1  defb 15
score2  defb 32

Printed value is 8207 - why and how to fix it? Without the last line everything is Ok. Printing the value with the other method gives the same result.


Solution

  • Yes, exactly; using defw will increase the size of the data (2 bytes each) to match the data size specification of the instruction being used in code.

    Code and data sizes have to match; each instruction that references data tells the CPU what size the data has, and, data declarations also have a size.  In many assembly languages, consistency is programmer responsibility — assemblers often do not complain about (size) mismatches.

    The CPU never sees data declarations, it only sees instructions.  So, each and every time an instruction references data, it has to specify how (i.e. the data size).  The CPU doesn't remember or care about mismatches between code in one place and code in another place, or between code & data; it just takes one instruction at a time and does what that says.

    Expanding the data to match what the code does is the easiest fix here because your print subroutine takes the argument to print in the bc 16-bit register pair.


    Otherwise, you can change the instruction to use the same size load as the defb, namely byte-sized instead of word-sized.  This would be done using an instruction like LD c,(score1), which loads only the c 8-bit register — and this is appropriate for data declared to 8-bits using defb.

    To continue and use the print function, however, since the print expects a value in 16-bit bc, the 8-bit value in c will have to be expanded to a 16-bit value in bc, by clearing b (set b to 0, or by sign extending into b).

    If I got the endian wrong, then swap references to the 8-bit registers with one letters b and c in what I said above.