[A83] Re: Negative numbers


[Prev][Next][Index][Thread]

[A83] Re: Negative numbers




I will assume that you are talking about native numbers, and not the
floating point format used by the ROM.  The floating point values will, of
course, support negative numbers, as bit 7 of the first byte is the sign
byte.

Negative numbers in assembly language is a bit complicated, but not that
difficult to grasp once you think about what is really going on.  First,
there is no such thing as signed numbers.  I think the most useful thing
that I learned in 8th grade math is that there is no subtraction.  The first
step to any problem is replacing all subtraction with addition.  That one
piece of advice is incredibly useful and makes doing math much easier.

There is no arbitrary distinction between signed and unsigned numbers.  It
all depends on what you are doing with them, and how you interpret them.
Now, certain operations do require you to care if the number is signed or
unsigned.  But for the built in instructions, they work just fine with
worrying about that.

You can use negative numbers as constants in a program.  Since many people
have trouble understanding what the assembler does, it is necessary to
examine this.  The exact value of a negative number depends on the size of
the number.  -2 will be different, depending on if the value is 8 or 16
bits.  But what value is it, exactly?  Well, this is easy to figure out, if
you think about the range of a value.  Take 0, and decrement it.  What do
you get?  -1, of course.  But what is that?  What value would become 0 when
incremented?  For 8 bits, 255, for 16 bits, 65535.  This means that -1 is
$FF or $FFFF, and -2 is $FE or $FFFE.

Looking at the number in binary, you'll see that the most significant bit is
the sign bit.  This means that for signed numbers, the maximum value is
halved.  For 8 bit numbers, you now have a range of -128 to 127, instead of
0 to 255.  Negative numbers go "backwards" from positive numbers.  Negative
numbers are also one off from their positive counter parts.  This means that
to calculate the negative value of a value, you increment the value, and
take the one's complement.  In z80, the "neg" instruction is equal to the
"inc a \ cpl" instructions.

When adding or subtracting values of the same size, the signedness of the
values does not matter.  When converting to different sizes, it matters.  To
convert an 8 bit signed value to a 16 bit signed value, it is necessary to
"sign extend" the value.  If the sign bit is not set, then the value can be
just be copied, as with an unsigned number.  Otherwise, the high byte is set
to all 1's, and the high bit of the low byte is set to 0.  An example is
shown below:

; signed value: A -> DE
 ld d,0
 ld e,a
 rla
 jr nc,notneg
 dec d
 res 7,e
notneg:

Another thing to remember with signed numbers is that you can't always use
the flags like you can with unsigned numbers.  With unsigned numbers, you
always check the carry flag.  With signed numbers, you usually check the
sign flag instead of the carry flag.

> How does the calc store negative numbers, and do negative numbers
> "survive" (I
> mean : are still recognised as negative numbers) some operations like
> push/pop, storing in RAM, etc. ?






Follow-Ups: