Difference between revisions of "680x0:Simple calculations"
Spellcoder (talk | contribs) (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...) |
Spellcoder (talk | contribs) (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 | + | <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 | ||
− | + | </code> | |
− | + | Multiplying/dividing: | |
− | <code | + | <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 | ||
− | </ | + | </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). | ||
− | + | <code> | |
− | + | TODO | |
− | + | </code> | |
− | |||
− | |||
− | |||
− | + | ===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.