User Tools

Site Tools


base:mathematics_in_assembly_part_1

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

base:mathematics_in_assembly_part_1 [2015-04-17 04:32] (current)
Line 1: Line 1:
 +====== Prologue ======
  
 +Hello dear readers. I noticed a need for some tutorials on coding and decided to
 +re-publish the texts i have been writing fo "​GO64!"​ magazine. Cactus gave me the
 +impulse to do that. "​Attitude"​ is the first diskmag to publish a chapter of the
 +tutorial on maths in assembly. The following chapters will be published in this
 +mag and also other ones like "​Vandalism News" and "​Domination"​. Just watch out.
 +Many thanks so Cosowi/​Plush,​ the publisher of "​GO64!",​ for the kind of permission
 +to re-publish these articles.
 +
 +====== Mathematics in Assembly ======
 +
 +Calculations in machine language are anything else than trivial: the command set
 +of the C-64 supplies all powerful operations - addition, subtraction,​ shift and
 +rotate, and that's it. That's sufficient for the beginning, but when it comes to
 +coding demos it isn't any more. An alternative would be to use the accurate
 +floating point routines of the Kernel, but they are far from what we call fast
 +and optimized. What we need are selfmade, fast and sufficiently accurate routines.
 +
 +Fixed point arithmetic routines are fast and accurate enough. They enable us to
 +easily define the necessary accuraxy (i.e. the amount of fraction bits) and the
 +computational range that means the range of numbers the routines ar appliable on.
 +A common example would be 0 through 65535 ($0000 through $FFFF. without sign) or
 +-32768 through 32767 ($8000 through $7fff, with sign), respectively. But more on
 +that later.
 +
 +====== The Basics: Binary Representation of Numbers ======
 +
 +This tutorial assumes basic knowledge of assembly language and the hexadecimal/​
 +binary number system. It should be clear how such a hex number looks like.
 +Alright, so we know common hex numbers on the C-64. Usually they range from 0
 +through 255, which equals $00 through $FF. But whar if we also need negative
 +numbers for our computations?​
 +
 +====== Negative Numbers in Assembly? ======
 +
 +Very simple, we just divide the range in half. This means we use one half of the
 +range for positive, the other one for negative numbers. The positive half ranges
 +lfrom 0 through 127 (0 is positive for a computer) and the negative from -128
 +through -1. Basically there are two ways to binary represent signed numbers where
 +it turned out to be most useful to use the upmost bit (MSB, Most Significant Bit),
 +which is bit 7 in the simplest case, as the sign. Acleared bit means a positive
 +number, a set bit a negative number. One could represent for instance -3 as $83
 +(binary %10000011), but this is not a very clever solution. The so-called two's
 +complement is the way to go. Basically this means if we want to have a negative
 +number, we subtract its absolute value from zero. Sounds logical, as -3 is 0-3.
 +This means in hex: -3 = $00-$03 = $FD, for 8 bit large numbers. Because of that,
 +-1 is not $81, but $FF. An alternative way of calculating negative numbers would
 +be th negate them bit-wise (i.e. perform an EOR #$FF) and afterwards add 1. The
 +result is the same while the later method is faster. So why do we do it like this?
 +It's because this system makes additions and subtractions very easy. Just imagine
 +we'd use the mentioned naive system where -1 would be $81. For a simple addition,
 +the signs had to be checked first, the numbers made positive accordingly (in case
 +they are negative) and afterwards their absolute values had to be subtracted or
 +added, depending on the numbers'​ signs. Not very effective.
 +
 +====== Signed Addition and Subtraction ======
 +
 +Using the two's complement system, the whole deal is extremely simple: -5+4 is -1.
 +In assembly this would be: $FB+$04=$FF. Analogous to that 8-12=-4, so $08-$0C=$FC.
 +That should be clear. But the command set of the 6502 processor family also
 +features the shiftand rotate commands. So how to take care of the sign there?
 +
 +====== Signed Shift and Rotate ======
 +
 +Shifting left doubles, shifting right halves a number. Now we should be a bit more
 +cautious. Doubling 5 makes 10, so $05+$05=$0A. Shifting left gives exactly this
 +result (the number to be doubled must not be larger than 127, as 2X128 would
 +already be 256 (=$0100), which doesn'​t fit into our number range of $00 through $ff
 +- using the carry bit here would help us, but more on that later). Shifting right
 +(halving) for instance $24 makes $12 which is also correct (but here we have to
 +take care off odd numbers, bit 0 is pushed into the carry bit). Obviously there are
 +no problems with positive numbers. Rather with negative ones. Shifting a number
 +like $EC (-20 or %11101100) left results in $D8 (-40 or %11011000). Exactly. But
 +trying to halve it again using LSR, the result is not $EC but $6C(108 or %01101100).
 +
 +====== The problem with halving and a negative sign ======
 +
 +The reason is clear, the upmost bit was lost before. Now it becomes obvious why the
 +command shifting left has different "​properties"​ than the one shifting right: left
 +is "​arithmetic"​ (ASL), and right is only "​logical"​ (LSR) because the correct sign
 +is preserved when shifting left in opposite to shifting right. So what to do? Very
 +simple. The sign just has to be preserved when shifting right. Shifting a negative
 +number right, the result has to be negative, too. This is the first time the rotate
 +commands are useful. Some small example code:
 +
 +<​code>​
 +LDA #$EC ; -20
 +CMP #$80 ; MSB to carry bit
 +ROR      ; halve
 +</​code>​
 +
 +Now the correct result, $F6 (-10, %11110110), is computed. This routine of course
 +also gives correct results for positive numbers. The absolute value of a doubled
 +number must not be larger than 127 ($7F), otherwise the number range had to be
 +enlarged to more than 8 bits. As mentioned before, the carry bit can be used to
 +help if doubled number exceeds the number range, as an ASL or ROL commands pushes
 +the upmost bit to the carry bit which can be taken care of afterwards.
 +
 +This was just the beginning. Enough for now. Just take your time to digest the
 +whole thing. In the next part of this turorial the small 8-bit number range will
 +be pumped up a little, up- and downwards.
base/mathematics_in_assembly_part_1.txt ยท Last modified: 2015-04-17 04:32 (external edit)