Difference between revisions of "680x0:Simple calculations"

From Amiga Coding
Jump to: navigation, search
(New page: Simple calculations: <code><pre> move.l #5,d0 ; d0 = $00000005 add.l #1,d0 ; d0 = d0 + 1 (d0 is now $00000006) sub.l #2,d0 ; d0 = d0 - 2 (d0 is now $00000004) rts </pre></co...)
 
(rewrote part about multiplication..etc.)
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
 +
==Examples==
 +
Whe'll start of with some examples before starting to discuss the sublities of doing calculations in assembler.
 +
 +
 
Simple calculations:
 
Simple calculations:
<code><pre>
+
<code lang="m68k">
 
move.l #5,d0 ; d0 = $00000005
 
move.l #5,d0 ; d0 = $00000005
 
add.l #1,d0 ; d0 = d0 + 1      (d0 is now $00000006)
 
add.l #1,d0 ; d0 = d0 + 1      (d0 is now $00000006)
 
sub.l #2,d0 ; d0 = d0 - 2      (d0 is now $00000004)
 
sub.l #2,d0 ; d0 = d0 - 2      (d0 is now $00000004)
 
rts
 
rts
</pre></code>
+
</code>
  
  
Harder calculations:
+
Multiplying/dividing:
<code><pre>
+
<code lang="m68k">
 
move.l #5,d0 ; d0 = $00000005
 
move.l #5,d0 ; d0 = $00000005
 
mulu.w #4,d0 ; d0 = d0 * 4
 
mulu.w #4,d0 ; d0 = d0 * 4
 +
divu.w  #2,d0          ; d0 = d0 / 2
 
rts
 
rts
</pre></code>
+
</code>
 +
 
 +
 
 +
Bit shifts:
 +
<code lang="m68k">
 +
move.l  #%11101,d0      ; d0 = %11101
 +
asl.l  #3,d0          ; d0 = d0 << 3 = %11101000
 +
</code>
 +
 
 +
 
 +
==Multiplying and dividing==
 +
Multiplying and dividing can be very usefull. But also keep in mind these are very slow to perform for a MC680x0 processor. For that reason democoders often try to find ways to find a quicker way to get comparable results or use a different way of doing the multiplication/division (for example with bitshifting).
 +
 
 +
 
 +
===Multiplication===
 +
For multiplication there's mulu (MULtiply Unsigned) and muls (MULtiply Signed). The standard mulu.w or muls.w can only multiply 16-bit numbers and '''although the result too is 16-bit, the result will be stored as a longword (32-bit).''' This means the upper part of the register will be cleared.
 +
 
 +
An example:
 +
<code lang="m68k">
 +
move.l  #$FFFFFFFF,d0    ; d0 = $FFFF.FFFF
 +
move.l  #5,d1
 +
move.l  #8,d2
 +
mulu.w  d1,d2            ; d0 = $0000.0028
 +
</code>
 +
 
 +
 
 +
As you can see:
 +
* the upper part will be cleared
 +
* mulu.w (MULtiply Unsigned) can only handle up to 65,535
 +
* muls.w (MULtiply Signed) can only handle from -32,768 to +32,767
 +
 
 +
 
 +
For 68020+ processors there's mulu.l and muls.l which can multiply two longwords (32-bit) and store the result into one register (only the low 32-bit) or two (for 64-bit).
  
  
The standard mulu (MULtiply Unsigned) only works with words
+
<code>
so can only handle numbers up to 65535. There is an command
+
TODO
for 68020+ processors and there are routines to multiply
+
</code>
using longwords but whe'll ignore them for now ;)
 
  
divu uses the lower word for the quotient (the result) and
 
the upper word for the remainder.
 
  
mulu doesn't use the upper word.
+
===Dividing===
 +
TODO
 +
...
 +
divu uses the lower word to store the quotient (the result) and the upper word to store the remainder.

Latest revision as of 02:23, 18 May 2008

Examples

Whe'll start of with some examples before starting to discuss the sublities of doing calculations in assembler.


Simple calculations: move.l #5,d0 ; d0 = $00000005 add.l #1,d0 ; d0 = d0 + 1 (d0 is now $00000006) sub.l #2,d0 ; d0 = d0 - 2 (d0 is now $00000004) rts


Multiplying/dividing: move.l #5,d0 ; d0 = $00000005 mulu.w #4,d0 ; d0 = d0 * 4 divu.w #2,d0  ; d0 = d0 / 2 rts


Bit shifts: move.l #%11101,d0  ; d0 = %11101 asl.l #3,d0  ; d0 = d0 << 3 = %11101000


Multiplying and dividing

Multiplying and dividing can be very usefull. But also keep in mind these are very slow to perform for a MC680x0 processor. For that reason democoders often try to find ways to find a quicker way to get comparable results or use a different way of doing the multiplication/division (for example with bitshifting).


Multiplication

For multiplication there's mulu (MULtiply Unsigned) and muls (MULtiply Signed). The standard mulu.w or muls.w can only multiply 16-bit numbers and although the result too is 16-bit, the result will be stored as a longword (32-bit). This means the upper part of the register will be cleared.

An example: move.l #$FFFFFFFF,d0  ; d0 = $FFFF.FFFF move.l #5,d1 move.l #8,d2 mulu.w d1,d2  ; d0 = $0000.0028


As you can see:

  • the upper part will be cleared
  • mulu.w (MULtiply Unsigned) can only handle up to 65,535
  • muls.w (MULtiply Signed) can only handle from -32,768 to +32,767


For 68020+ processors there's mulu.l and muls.l which can multiply two longwords (32-bit) and store the result into one register (only the low 32-bit) or two (for 64-bit).


TODO


Dividing

TODO ... divu uses the lower word to store the quotient (the result) and the upper word to store the remainder.