flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
cwpjr 31 Oct 2012, 22:02
I should have said this is a unsigned double ( 64bit ) divided by an unsigned single ( 32 but ) routine....
|
|||
![]() |
|
tthsqe 31 Oct 2012, 23:23
I'm assuming you want this in 32-bit mode.
A: 64 bit unsigned (input) B: 32 bit unsigned (input) Q: 64 bit unsigned (output) R: 32 bit unsigned (output) The output is determined so that A=Q*B+R and R<B Code: xor edx,edx mov eax,dword[A+4] div dword[B] mov [Q+4],eax mov eax,dword[A+0] div dword[B] mov [Q+0],eax mov [R],edx |
|||
![]() |
|
revolution 01 Nov 2012, 00:20
cwpjr wrote: I need to get the remainder into r2, Quotient = int ( Divisor / Dividend ) ;UDIV only does this part Remainder = Divisor - Quotient * Dividend ;This part you need to add |
|||
![]() |
|
tthsqe 01 Nov 2012, 01:52
wait, was the goal a translation to ARM, or a translation to x86?
|
|||
![]() |
|
cwpjr 01 Nov 2012, 02:05
And thanks so much for the help.
Translating from the x86 commented out code to arm and the output is specified as: r2 = u32REMAINDER, r0 = u32QUOTIENT Again thanks for you kind considerations... The comments are so succinct. Sorry about the target confusion, that's why I edited the original subject with [ARM] and posted in the Non-x86 architectures thread... smile. _________________ Developing ARM Electronic Hobby Bench Stuff! |
|||
![]() |
|
cwpjr 01 Nov 2012, 04:14
revolution wrote:
So I see this possibility... mov r1, r0 ; save divisor udiv r0, r0 , r4 ; r0 is QUOTIENT of divisor(r0) / dividend HI(r4) MLS r2, r0, r2, r1 ; r2 is remainder as divisor(r1) - quotient (r0) * dividend LO(r2) But my math savant tells me beware here....HELP! I love computers because once i get it right they do math for me! In other words I suck at math and appreciate the crutch! _________________ Developing ARM Electronic Hobby Bench Stuff! |
|||
![]() |
|
revolution 01 Nov 2012, 04:29
Are you doing 64-bit or 32-bit computations? You seem to be mixing things up there. If your values are 64-bit then you can't simply use the 32-bit instructions like that. Instead you will need to write a full 64-by-64 divider.
|
|||
![]() |
|
cwpjr 01 Nov 2012, 16:48
FIRST LET ME POST THE 16 BIT X86 ROUTINE I'M TRYING TO TRANSLATE TO 32BIT ARM THUMB2 CODE:
(; COMMENTS ARE MINE, IT CAME WITH NONE) POP BX ; UMSW POP BX dividendHI POP DX ; ULSW POP DX dividendLO POP AX ; U32 POP AX divisor CMP DX,BX ; DIV BY 0 IF BOTH DIVIDENDS ARE 0? JNB DZERO DIV AX,BX ; SOMEHOW INCLUDES DX? ; AND LEAVES DX AS MODULO? JMP DPUSH ; SAVE DX AND AX DZERO: MOV AX,-1 MOV DX,AX JMP DPUSH ; SAVE DX AND AX AS FAR AS I CAN TELL THE ABOVE ORIGINAL X86 CODE IS 16 BIT WHERE THE DOUBLE IS TWO 16 BIT UNSIGNED NUMBERS AND THE DIVIDEND IS A 16 BIT UNSIGNED NUMBER. ; HERE ARE COMMENTS FROM X86 ISA REFERENCE ;when operand is a word: DIV AX,DX ;AX = (DX AX) / operand ;DX = remainder (modulus) LIKE THE ABOVE MY 32 BIT SPEC FOR THIS ROUTINE IS MIXED - THE DIVIDEND IS A UNSIGNED 64 BIT NUMBER WHERE 1 - 0 1 (BOTH 32 BITS) AND THE DIVISOR IS A 32BIT UNSIGNED NUMBER. THE QUOTIENT IS RESULT IS AN UNSIGNED 32 BIT NUMBER AND THE REMAINDER IS ALSO, AND IF THIS MEANS ANYTHING IT IS CALLED A MODULO. I AM TRYING TO IMPLEMENT THIS AS A 32 BIT VERSION. THE 16 BIT X86 VERSION SEEMS TO USE ONE INSTRUCTION... HOPE THIS HELPS. SORRY ABOUT ALL CAPS. |
|||
![]() |
|
revolution 02 Nov 2012, 03:09
Okay, so you are doing a 64-by-32 divide. UDIV can't help you to do it in one instruction because it only takes a single 32-bit value for each of the dividend and divisor. You will need to write a full division routine to do what you need. A standard bitwise shift and subtract method is probably the easiest to code and understand. If you need it done quickly because of a performance problem then there are other more efficient methods but I think they are beyond the scope of the topic. Might be good for another topic though.
BTW: I made an error above; I exchanged the dividend and divisor incorrectly. It should of course read: Quotient = int ( Dividend / Divisor ) ;UDIV only does this part Remainder = Dividend - Quotient * Divisor ;This part you need to add |
|||
![]() |
|
cwpjr 03 Nov 2012, 19:18
Thanks, Revolution.
One last though. udiv is giving me a proper 32 / 32 result. however "Remainder = Dividend - Quotient * Divisor ;This part you need to add" does not seen to work for me in a MLA ARM instruction form of any kind. I'm saying I can live with a 32x32 udiv and a 32 remainder/modulo and thought that would work. Thanks, Clyde |
|||
![]() |
|
revolution 04 Nov 2012, 00:44
Does this not work?
Code: ;input ;r0 = dividend ;r1 = divisor ;output ;r2 = quotient ;r3 = remainder udiv r2,r0,r1 ;r2=int(r0/r1) mls r3,r2,r1,r0 ;r3=r0-r2*r1 |
|||
![]() |
|
cwpjr 04 Nov 2012, 20:35
Revolution I must thank you so much. Since I last coded 10+ years ago, I have developed some dyslexia. My solution was the same as yours but with a dyslexic implementation. It was driving me crazy! And probably not fun for you.
Your kind patience with me has allowed me to both see and correct for my issue, resulting in a wonderful feeling of... YESSSSSS!!!!!! I finally got this dang function working! And now that I know what to correct for I'm just back to having lousy math skills! :>) Clyde |
|||
![]() |
|
revolution 05 Nov 2012, 12:22
Remember to plan for possible division by zero. Depending upon your OS settings it may or may not generate an exception.
|
|||
![]() |
|
cwpjr 08 Nov 2012, 16:59
YOU BET. The black box system I'm translating from appears to return divide by zero (-1) if the dividend msw is zero but anther routine that supposedly uses this routine is a mixed mode multiple/divide and one with modulo output, where both generate results that can't ignore the dividend msw.
I'm learning enough about this crap that I think in a bit I'll write a spec and write my own. Then I am to blame if it is incoherent! Cheers, Clyde |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.
Website powered by rwasa.