where : ibrtses embedded
AVR math
ASM
signed16 multiplied with unsigned8 - limited
assumed the CPU supports the required commands
all in CSEG :
; multiply S16:=S16*U8 with overflow protection both ways
;
; result:= Z^, S16:=Y^, U8:=u1 16 bit as little endian
;
; there is no overflow bigger than 0x7FFF or smaller 0x8000
MulS16U8:
push temp
push u2
push u3
push u4
push u5
clr u2 ; low result
clr u3 ; high result
ld u4,Y ; low S16
ldd u5,Y+1 ; high S16
ldd temp,Y+1 ; get sign of S16
andi temp,0x80
brne ms16u8_1
; positive
ms16u8_0:
lsr u1
brcc ms16u8_3 ; skip
add u2,u4
adc u3,u5
mov temp,u3
andi temp,0x80
brne ms16u8_2 ; positive overflow
ms16u8_3:
tst u1
breq ms16u8_end ; end
lsl u4 ; shift left
rol u5
brmi ms16u8_6 ; goes negative
rjmp ms16u8_0 ;again
ms16u8_2: ;positive overflow
ldi u2,0xFF ; set max number 0x7FFF
ldi u3,0x7F
rjmp ms16u8_end ; end
ms16u8_6: ; shift goes negative
tst u1 ; set overflow if more to add
brne ms16u8_2
rjmp ms16u8_end ; or terminate if end
; negative
ms16u8_1:
lsr u1
brcc ms16u8_4 ;skip
add u2,u4
adc u3,u5
mov temp,u3
andi temp,0x80
breq ms16u8_5 ;negative overflow
ms16u8_4:
tst u1
breq ms16u8_end ;end;
lsl u4
rol u5
brpl ms16u8_7 ; goes positive
rjmp ms16u8_1 ;again
ms16u8_5: ;negative overflow
ldi u2,0x00 ; set min number=0x8000
ldi u3,0x80
rjmp ms16u8_end ; end
ms16u8_7: ;shift goes positive
tst u1 ; set overflow if more to add
brne ms16u8_5
ms16u8_end:
st Z,u2
std Z+1,u3
pop u5
pop u4
pop u3
pop u2
pop temp
ret
add 2 signed 16 bit - limited
assume U1..U3 as R16..R31
;addition of 2 signed 16 bit with overflow protection
; add into 24 bit then test
;
; result:= Z^, S16:=Y^, Z^:=Z^+Y^ 16 bit as little endian
;
; there is no overflow bigger than 0x7FFF or smaller 0x8000
addS16:
push temp
push u1
push u2
push u3
push u4
push u5
ld u2,Z ; low result
ldd u3,Z+1 ; high result
ld u4,Y ; low S16
ldd u5,Y+1 ; high S16
tst u3
brpl as16_1
; neg Z
tst u5
brpl as16_2
; neg + neg
add u2,u4
adc u3,u5
brmi as16_end
; neg + neg overflow
ldi u2,0x00
ldi u3,0x80
; ok
rjmp as16_end
; neg + pos
as16_2:
add u2,u4
adc u3,u5
rjmp as16_end
; pos + neg
as16_3:
add u2,u4
adc u3,u5
rjmp as16_end
; pos Z
as16_1:
tst u5
brmi as16_3
; pos + pos
ldi temp,0
ldi u1,0
add u2,u4
adc u3,u5
brpl as16_end
; pos + pos overflow
ldi u2,0xFF
ldi u3,0x7F
as16_end:
st Z,u2
std Z+1,u3
pop u5
pop u4
pop u3
pop u2
pop u1
pop temp
ret
Questions ?
Suggestions?
Feedback ?
sponsored links
disclaimer
AVR index
embedded software pages
home
last updated: 18.sept.00
Copyright (99,2001) Ing.Büro R.Tschaggelar