ASM 32-bit division routine?
2008-07-29 by Enki
Yahoo Groups archive
Index last updated: 2026-04-28 22:41 UTC
Thread
2008-07-29 by Enki
Hi, I'm looking for a 32-bit by 16-bit integer division routine in assembler. The rest of division is not important. I don't need it. Have googled and didn't found any I liked. Any recommendations? Thanks. Mark Jordan
2008-07-29 by John Samperi
At 11:15 PM 29/07/2008, you wrote:
>I'm looking for a 32-bit by 16-bit integer division
Will 32 by 32 do?
;-----------------------------------------------------------------------------:
; 32bit/32bit Unsigned Division
;
; Register Variables
; Call: var1[3:0] = dividend (0x00000000..0xffffffff)
; var2[3:0] = divisor (0x00000001..0x7fffffff)
; mod[3:0] = <don't care>
; lc = <don't care> (high register must be allocated)
;
; Result:var1[3:0] = var1[3:0] / var2[3:0]
; var2[3:0] = <not changed>
; mod[3:0] = var1[3:0] % var2[3:0]
; lc = 0
;
; Size = 26 words
; Clock = 549..677 cycles (+ret)
; Stack = 0 bytes
div32u: clr mod0 ;initialize variables
clr mod1 ; mod = 0;
clr mod2 ; lc = 32;
clr mod3 ;
ldi lc,32 ;/
;---- calcurating loop
lsl var10 ;var1 = var1 << 1;
rol var11 ;
rol var12 ;
rol var13 ;/
rol mod0 ;mod = mod << 1 + carry;
rol mod1 ;
rol mod2 ;
rol mod3 ;/
cp mod0,var20 ;if (mod => var2) {
cpc mod1,var21 ; mod -= var2; var1++;
cpc mod2,var22 ; }
cpc mod3,var23 ;
brcs PC+6 ;
inc var10 ;
sub mod0,var20 ;
sbc mod1,var21 ;
sbc mod2,var22 ;
sbc mod3,var23 ;/
dec lc ;if (--lc > 0)
brne PC-19 ; continue loop;
ret
Regards
John Samperi
********************************************************
Ampertronics Pty. Ltd.
11 Brokenwood Place Baulkham Hills, NSW 2153 AUSTRALIA
Tel. (02) 9674-6495 Fax (02) 9674-8745
Email: john@ampertronics.com.au
Website http://www.ampertronics.com.au
*Electronic Design * Custom Products * Contract Assembly
********************************************************2008-07-29 by Don Kinzer
--- In AVR-Chat@yahoogroups.com, "Enki" <enkitec@...> wrote: >I just deleted the mod2 and mod3 lines to transform your routine to > 32bit/16bit. Presumably, you adjusted the PC-relative addresses given with the branch instructions, too. A less error-prone method is to introduce labels to use for the branch destinations thus letting the assembler figure out the branch distance. I've been bitten more than once when using PC-relative addresses by adding instructions between the branch and destination and forgetting to adjust the offset. The downside, of course, is that you have to invent a label name. The Atmel AVR Assembler documentation seems to suggest that a label must be on a line preceding a directive, instruction, etc. However, it does accept a label on a line by itself which is, I think, the preferable alternative. As a side note, the gcc assembler supports the use of numeric labels (like 2:) and then allows you to refer to them using, for example, 2f and 2b to refer to the first 2: forward and the first 2: backward. This precludes the need to invent a label name and it is also useful in macros that are used multiple times, avoiding problems with duplicate label names. Don Kinzer ZBasic Microcontrollers http://www.zbasic.net
2008-07-29 by Enki
On 30 Jul 2008 at 4:39, John Samperi wrote:
> At 11:15 PM 29/07/2008, you wrote:
> >I'm looking for a 32-bit by 16-bit integer division
>
> Will 32 by 32 do?
>
> ;-------------------------------------------------------------------
> ----------:
> ; 32bit/32bit Unsigned Division
> ;
> ; Register Variables
> ; Call: var1[3:0] = dividend (0x00000000..0xffffffff)
> ; var2[3:0] = divisor (0x00000001..0x7fffffff)
> ; mod[3:0] = <don't care>
> ; lc = <don't care> (high register must be
> allocated)
> ;
> ; Result:var1[3:0] = var1[3:0] / var2[3:0]
> ; var2[3:0] = <not changed>
> ; mod[3:0] = var1[3:0] % var2[3:0]
> ; lc = 0
> ;
> ; Size = 26 words
> ; Clock = 549..677 cycles (+ret)
> ; Stack = 0 bytes
>
>
> div32u: clr mod0 ;initialize variables
> clr mod1 ; mod = 0;
> clr mod2 ; lc = 32;
> clr mod3 ;
> ldi lc,32 ;/
> ;---- calcurating loop
> lsl var10 ;var1 = var1 << 1;
> rol var11 ;
> rol var12 ;
> rol var13 ;/
> rol mod0 ;mod = mod << 1 + carry;
> rol mod1 ;
> rol mod2 ;
> rol mod3 ;/
> cp mod0,var20 ;if (mod => var2) {
> cpc mod1,var21 ; mod -= var2; var1++;
> cpc mod2,var22 ; }
> cpc mod3,var23 ;
> brcs PC+6 ;
> inc var10 ;
> sub mod0,var20 ;
> sbc mod1,var21 ;
> sbc mod2,var22 ;
> sbc mod3,var23 ;/
> dec lc ;if (--lc > 0)
> brne PC-19 ; continue loop;
> ret
>
>
>
> Regards
>
> John Samperi
>
Thank you, John!
I just deleted the mod2 and mod3 lines to transform your routine to
32bit/16bit. Worked nicely!
Mark Jordan2008-07-29 by Cat Hotmail
Don Kinzer, you know so much! Even though I'm planning to avoid assembler as much as I can... I'm amazed at the level of detail you know. Thank you! Cat --------------------------------------------------
From: "Don Kinzer" <dkinzer@easystreet.net> Sent: Tuesday, July 29, 2008 5:29 PM To: <AVR-Chat@yahoogroups.com> Subject: [AVR-Chat] Re: ASM 32-bit division routine? > --- In AVR-Chat@yahoogroups.com, "Enki" <enkitec@...> wrote: >>I just deleted the mod2 and mod3 lines to transform your routine to >> 32bit/16bit. > Presumably, you adjusted the PC-relative addresses given with the > branch instructions, too. A less error-prone method is to introduce > labels to use for the branch destinations thus letting the assembler > figure out the branch distance. I've been bitten more than once when > using PC-relative addresses by adding instructions between the branch > and destination and forgetting to adjust the offset. The downside, of > course, is that you have to invent a label name. > > The Atmel AVR Assembler documentation seems to suggest that a label > must be on a line preceding a directive, instruction, etc. However, > it does accept a label on a line by itself which is, I think, the > preferable alternative. > > As a side note, the gcc assembler supports the use of numeric labels > (like 2:) and then allows you to refer to them using, for example, 2f > and 2b to refer to the first 2: forward and the first 2: backward. > This precludes the need to invent a label name and it is also useful > in macros that are used multiple times, avoiding problems with > duplicate label names. > > Don Kinzer > ZBasic Microcontrollers > http://www.zbasic.net > > > > ------------------------------------ > > Yahoo! Groups Links > > > >
2008-07-30 by John Samperi
At 08:45 AM 30/07/2008, you wrote: > just deleted the mod2 and mod3 lines to transform your routine to >32bit/16bit. Worked nicely! Not my routine unfortunately. Not clever enough. :-) But I have a collection of useful bits around. Regards John Samperi ******************************************************** Ampertronics Pty. Ltd. 11 Brokenwood Place Baulkham Hills, NSW 2153 AUSTRALIA Tel. (02) 9674-6495 Fax (02) 9674-8745 Email: john@ampertronics.com.au Website http://www.ampertronics.com.au *Electronic Design * Custom Products * Contract Assembly ********************************************************
2008-07-30 by John Samperi
At 09:29 AM 30/07/2008, you wrote: >A less error-prone method is to introduce >labels to use for the branch destinations thus letting the assembler >figure out the branch distance. I guess there is a need to clean up those routines if I use them. Don't know where I got them from, I have 8, 16, 24 and 32 bits division in my library folder. So far I have only had to use the Atmel 8 and 16 bits maths routines. (AVR200 and AVR200b) Regards John Samperi ******************************************************** Ampertronics Pty. Ltd. 11 Brokenwood Place Baulkham Hills, NSW 2153 AUSTRALIA Tel. (02) 9674-6495 Fax (02) 9674-8745 Email: john@ampertronics.com.au Website http://www.ampertronics.com.au *Electronic Design * Custom Products * Contract Assembly ********************************************************