division in assembly using k40 kwikstik

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

division in assembly using k40 kwikstik

Jump to solution
2,229 Views
derill03
Contributor I

Can anyone help with how to do a division and get a remainder in ASSEMBLY language not C using kwikstik K40? I try to use the instruction

 

.external div

 BL div

 

I can not find any info on what registers are to be used to hold what values if using in assembly, so it crashes when it runs the function, but it does compile and call the function.

 

All i need to do is calculate a remainder after division like the following:

 

A0 = D1/10              // D1 being some number

D0 = D1 mod 10

 

but there is no modulo operation in the ARM K40 kwikstik so the only thing i found was to use the div() external function

0 Kudos
1 Solution
1,249 Views
ipa
Contributor III

It seems you are in a terrible rush, so let's start again (sorry):

 

First, from Wikipedia:

"In computing, the modulo operation finds the remainder of division of one number by another."

 

If you read carefully the second function written, (it is messy as resulted from listing):

udiv r3, r0, r1

mlsr0, r3, r1, r0

In two asm instruction you have the remainder: first instruction computes the quotient and the second (nice, very powerful Cortex, thanks ARM) is multiply with subtract (a-nq, see the Wikipedia page) so the result in r0 is the remainder. This holds true if you really use unsigned parameters.

 

ipa

View solution in original post

0 Kudos
5 Replies
1,249 Views
comsosysarch
Contributor III

All i need to do is calculate a remainder after division like the following:

A0 = D1/10              // D1 being some number

D0 = D1 mod 10

but there is no modulo operation in the ARM K40 kwikstik so the only thing i found was to use the div() external function

 

 

 

So D0 = D1 % 10 does not work in C?

 

If you want to call assembly from C, and you are asking which registers are used, you should probably refer to the ARM Cortex-M4 technical reference manual from ARM Inc. Online free. But here is the abridged version:

 

Arguments passed into a function are passed, in order, in registers R0 through R3. Arguments larger than 32 bits span multiple registers. If there is not enough room in 4 32-bit registers for all the function arguments then they are passed on the stack instead.

 

The same logic applies for values returned from a function, registers R0 through R3 with the stack used instead if that will not work.

 

Registers R0-R3, as well as R12, are always assumed to be "dirtied" by a function call. A calling function is responsible for pushing these prior to making a call and then popping to restore them when the call returns.

A _called_ function is responsible for pushing any other registers on the stack prior to using them and popping them off again to restore them before returning.

 

This is all per ARM. If that is what you were asking.

 

There is a pretty good short assembly language tutorial online at

http://www.coranac.com/tonc/text/asm.htm

if you want to dig a little deeper and maybe see what other pitfalls there are with register selection.

 

0 Kudos
1,249 Views
comsosysarch
Contributor III

Sorry / correction, in case someone bothers to check, that is the "ARM®v7-M Architecture Reference Manual" from ARM Inc that covers ARM assembly language in detail.

 

0 Kudos
1,249 Views
ipa
Contributor III

Hi,

The instruction syntax is:

UDIV{cmd} {Rd,} Rn, Rm

where:

Rd is destination register

Rn is dividend

Rm is divisor

 

Usually the compiler uses either internal intrinsics either just direct inline code. I wrote two small functions to see what the compiler generate and checked the listing. Here it is the result:

00000272 <IntDiv>:
// div
//
unsigned long IntDiv(unsigned long dividend, unsigned long divisor)
{
return (dividend/divisor);
}
272: fbb0 f0f1 udiv r0, r0, r1
276: 4770 bx lr

00000278 <Modulo>:

unsigned long Modulo(unsigned long dividend, unsigned long divisor)
{
return (dividend%divisor);
278: fbb0 f3f1 udiv r3, r0, r1
 27c: fb03 0011 mls r0, r3, r1, r0
280: 4770 bx lr

 

Regards,

ipa

0 Kudos
1,249 Views
derill03
Contributor I

I know of the UDIV instruction but it does not give the remainder, atleast not that i can tell from documentation. I need the remainder because im converting hex to decimal. So for instance i have number 132 if i divide it by 10 i will get 13 using UDIV, but all i care about is the 2 that was truncated by the division. Is there a way to get the remainder? hence to do a modulo 10?

 

In my first post i was trying to say I found an external c function called remainder() and one called div() to use in my assembly code but the remainder function gave some funny values and the div function just crashed.

 

Any help would be greatly appreciated

0 Kudos
1,250 Views
ipa
Contributor III

It seems you are in a terrible rush, so let's start again (sorry):

 

First, from Wikipedia:

"In computing, the modulo operation finds the remainder of division of one number by another."

 

If you read carefully the second function written, (it is messy as resulted from listing):

udiv r3, r0, r1

mlsr0, r3, r1, r0

In two asm instruction you have the remainder: first instruction computes the quotient and the second (nice, very powerful Cortex, thanks ARM) is multiply with subtract (a-nq, see the Wikipedia page) so the result in r0 is the remainder. This holds true if you really use unsigned parameters.

 

ipa

0 Kudos