16-bit assembly multiplication
When 8-bit microcontrollers have 11-bit PWM output, some 16-bit arithmetic may be required. The ATTiny13 and the PFS-154 do not have hardware multiplication (MUL or MULS) and so these operations need to be done in software.
Although there are a few different algorithms (both manual and automated) to multiply two numbers together, I have chosen to do the typical "shift and add" method that we are all taught in primary school.
In assembly, and for 16 bit multiplication, this means a code section on shifting the data to the right (multiplication by 10 for decimal, and 2 for binary):
rol r21 ; multiply by 2
rol r20 ; for next iteration
There is also a code section for adding two sixteen bit numbers:
add r23, r21 ; no so add lower
adc r22, r20 ; and upper bytes
The complete code is below, which runs great on Gerd's excellent AVR-SIM.
.nolist .include "tn13adef.inc" .list .dseg .org SRAM_START .cseg .org 000000 rjmp Main ; Reset vector Main: ; initialise stack ldi r16,Low(RAMEND) out SPL,r16 ; Init LSB stack pointer .equ mult1 = 27 ; 0x1B .equ mult2 = 58 ; 0x3A Loop: ; clear working registers clr r16 clr r17 clr r18 clr r20 clr r21 clr r22 clr r23 ; load numbers and counter ldi r17, mult1 ldi r21, mult2 ldi r18, 8 testbits: ; test each bit ror r17 brcc zero_partial ; is it a zero? add r23, r21 ; no so add lower adc r22, r20 ; and upper bytes zero_partial: rol r21 ; multiply by 2 rol r20 ; for next iteration subi r18, 1 ; decrement counter brne testbits ; any more left? rjmp loop ; start again
Next time in this series I'll do a program that makes 16-bit random numbers, and then maybe we'll start looking to program the PFS-154 in assembly - gulp!
No comments:
Post a Comment