flat assembler
Message board for the users of flat assembler.

Index > Windows > I need some division help.

Author
Thread Post new topic Reply to topic
2



Joined: 26 Sep 2006
Posts: 92
2 22 Nov 2006, 02:58
I have never used MUL or DIV . I normally don't mess with them,but I'm wanting to do a primes program by trial division since it's the only way I know
of. I've done it in C before. What I need is a way to divide something and
get the remainder.

Haven't seen very good reference on how to do this. Any help would be greatly appreciated. I'll check the FASM documentation again,but please tell me any useful things you know.

Also,can anybody find a way of division by 3 with only bitwise operations?
That would be cool if it was possible.

_________________
There are 10 kinds of people in the world.
Those who know binary and those who haven't met me.
Post 22 Nov 2006, 02:58
View user's profile Send private message Reply with quote
Filter



Joined: 08 Oct 2006
Posts: 67
Filter 22 Nov 2006, 03:31
The intel manuals say...
"Divides unsigned the value in the AX, DX:AX, EDX:EAX, or RDX:RAX registers (dividend)
by the source operand (divisor) and stores the result in the AX (AH:AL),
DX:AX, EDX:EAX, or RDX:RAX registers. The source operand can be a generalpurpose
register or a memory location. The action of this instruction depends on the
operand size (dividend/divisor)."

I think this means that when you divide the remainder is stored in EDX.
From what I understand...
Code:
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
        int result;
        int remainder;
        int divisor = 0x10;

        __asm
        {
                mov eax, 51h
                xor edx,edx
                div divisor
                mov [result],eax
                mov [remainder],edx
        }

        cout << "Result: " << result << " Remainder: " << remainder << endl;

        return 0;
}

    

... would place 5h in EAX and 1h in EDX.

Put the number you want to divide in EDX:EAX and then use the div instruction on a memory location or register that contains the number that you want to divide. The result ends up in EAX and the remainder in EDX.

Sorry for mixing C++ and ASM but I'm new to assembler and it was the quickest way for me to see the results. I'm learning too Smile
Post 22 Nov 2006, 03:31
View user's profile Send private message Reply with quote
2



Joined: 26 Sep 2006
Posts: 92
2 22 Nov 2006, 05:55
OK,I'm not sure about this,but I'll try. Thanks.
Post 22 Nov 2006, 05:55
View user's profile Send private message Reply with quote
Filter



Joined: 08 Oct 2006
Posts: 67
Filter 22 Nov 2006, 17:08
2 wrote:
OK,I'm not sure about this,but I'll try. Thanks.


Me neither but it worked.

The code between the brackets for __asm should work in FASM just fine.

I'm sure someone who is an asm guru will come along and explain it better than I can or maybe even show that I'm wrong somehow.
Post 22 Nov 2006, 17:08
View user's profile Send private message Reply with quote
OzzY



Joined: 19 Sep 2003
Posts: 1029
Location: Everywhere
OzzY 23 Nov 2006, 11:51
Here it is a fully working program for division, written in FASM:

Code:
include '%fasminc%\win32a.inc'
format PE console ; we want console program
entry main

section '.data' data readable writeable ;our variables
msg1 db 'Type the number: ',0

num1 dd 0

frmt1 db '%d',0
frmt2 db 'The result of the division is %d and the remainder is %d!',0

res dd 0
rem dd 0

section '.code' code readable executable ; our code
main:
        cinvoke printf,msg1     ; we print the first message
        cinvoke scanf,frmt1,num1; we read the number
        
        
        mov eax,[num1] ; we store the number in eax
        xor edx,edx
        mov ecx,2          ; we move 2 into ecx
        div ecx    ; do the division
        
        mov [res],eax   ; we get
        mov [rem],edx   ; the results
        cinvoke printf,frmt2,[res],[rem] ; we print the results

        
        invoke ExitProcess,0   ; we Exit the program

section '.idata' import data readable writeable ; our import section

  library kernel32,'kernel32.dll',\
          msvcrt,'msvcrt.dll'

  import kernel32,\
         ExitProcess,'ExitProcess'

  import msvcrt,\          ; Functions from C library
         printf,'printf',\
         scanf,'scanf'
    

I guess that's what you want.
You need to run it from the console to view the results.
This example shows division and how to print integers using the C library functions.
Enjoy!
Post 23 Nov 2006, 11:51
View user's profile Send private message Reply with quote
Filter



Joined: 08 Oct 2006
Posts: 67
Filter 24 Nov 2006, 03:37
That's fairly easy to understand. Thanks Ozzy.
Post 24 Nov 2006, 03:37
View user's profile Send private message Reply with quote
flaith



Joined: 07 Feb 2005
Posts: 122
Location: $300:20 58 FC 60 N 300G => Vietnam
flaith 24 Nov 2006, 08:32
From Ozzy's code, with the possibility to use signed division
Code:
include 'win32a.inc'
;include 'win32w.inc'
;include 'encoding\utf8.inc'

format PE console
entry main

section '.code' code readable executable
main:
        cinvoke printf,msg1            ;Demande du dividende
        cinvoke scanf,frmt1,_val1
        
        cinvoke printf,msg2            ;Demande du diviseur
        cinvoke scanf,frmt1,_val2

        xor     eax, eax
        mov     edx, 0                 ;obligatoire avant de faire la division (signe)
        mov     eax, dword [_val1]
        test    eax, eax               ;positionne le flag (pour vérifier le signe)
        js      negatif                ;il y a un signe ? oui donc saut
        jmp     cont
  negatif:
        mov     edx, -1                ;obligé, pour indiquer qu'il y a un signe négatif
  cont:
        mov     ebx, dword [_val2]
        idiv    ebx
        mov     dword [result], eax
        mov     dword [reste], edx     ;le reste de la division

        ;on affiche le résultat
        cinvoke printf,frmt2,[result],[reste]

        invoke  ExitProcess,0          ;On quitte

section '.data' data readable writeable
msg1    db 'Entrez le dividende : ',0
msg2    db 'Entrez le diviseur  : ',0

frmt1   db '%d',0
frmt2   db 'Le résultat de la division est : %d',13,10,\
           '                  le reste est : %d',0

_val1   dd 0
_val2   dd 0

result  dd 0
reste   dd 0

section '.idata' import data readable writeable

  library kernel32,'kernel32.dll',\
          msvcrt,'msvcrt.dll'

  import kernel32,\
         ExitProcess,'ExitProcess'

  import msvcrt,\
         printf,'printf',\
         scanf,'scanf'    


BTW, i tried to use "printf" with unicode support, but it seems that it doesn't work (tried with "du", etc...), do you know any others ways to use printf in unicode ? Thanks Smile

_________________
Je suis sur de 'rien', mais je ne suis pas sur du 'tout'.
Post 24 Nov 2006, 08:32
View user's profile Send private message Visit poster's website Reply with quote
peter



Joined: 09 May 2006
Posts: 63
peter 25 Nov 2006, 05:08
For Unicode support, try wsprintfW.
Post 25 Nov 2006, 05:08
View user's profile Send private message Visit poster's website Reply with quote
flaith



Joined: 07 Feb 2005
Posts: 122
Location: $300:20 58 FC 60 N 300G => Vietnam
flaith 25 Nov 2006, 20:41
thanks Peter Smile

_________________
Je suis sur de 'rien', mais je ne suis pas sur du 'tout'.
Post 25 Nov 2006, 20:41
View user's profile Send private message Visit poster's website Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 26 Nov 2006, 20:12
This is my old IsPrime function Laughing

Code:
        proc IsPrime,Value

                        mov eax,[Value]

                        cmp eax,0x00000001
                        je IsPrime_False

                        cmp eax,0x00000002
                        je IsPrime_True

                        and eax,0x00000001
                        cmp eax,0
                        je IsPrime_False

                        xor ecx,ecx
                        inc ecx

                 IsPrime_Do:

                        add ecx,2

                        mov eax,[Value]
                        xor edx,edx
                        div ecx
                        cmp edx,0
                        je IsPrime_False

                        mov eax,[Value]
                        shr eax,1
                        add eax,2
                        cmp ecx,eax
                        jae IsPrime_True

                        jmp IsPrime_Do

                 IsPrime_True:

                        xor eax,eax
                        not eax

                        jmp IsPrime_Exit

                 IsPrime_False:

                        xor eax,eax

                 IsPrime_Exit:

             endp
    


To divide by 3 with just bitwise operators (shr & add) you have to do:

1/3 ~ 1/2 - 1/4 + 1/8 - 1/16 + 1/32 - ...

which simplifies to:

1/3 ~ 1/4 + 1/16 + 1/64 + ...

The code should be simple to work out Cool

HTH
Post 26 Nov 2006, 20:12
View user's profile Send private message Reply with quote
Goplat



Joined: 15 Sep 2006
Posts: 181
Goplat 26 Nov 2006, 21:11
cod3b456: That won't always give an accurate answer though. 3/4 + 3/16 + 3/64 + ... = 0 + 0 + 0 + ... = 0, but 3/3 = 1.
Post 26 Nov 2006, 21:11
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 26 Nov 2006, 23:39
yeah, bitwise it is better to do:

3/3 ~ 3/2 - 3/4 + 3/8 - ... = 1 - 0 + 0 - ... = 1

Got carried away with the maths Embarassed
Post 26 Nov 2006, 23:39
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 27 Nov 2006, 00:25
Quote:
To divide by 3 with just bitwise operators

i think 67byte sudoku solver used "aam 11". But i never understood aam Sad
Post 27 Nov 2006, 00:25
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 27 Nov 2006, 01:03
AAM is also nothing but a division by a given immediate. Quotient goes into AH, and remainder goes into AL. You can consider it to be an 8-bit DIV by immediate with target registers being swapped. Wink
Post 27 Nov 2006, 01:03
View user's profile Send private message Visit poster's website Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo 30 Nov 2006, 06:08
Someone correct me if I'm wrong, but old NEC chips (20 and 30?) don't support AAM 11. (Of course, who cares but anyways ...)
Post 30 Nov 2006, 06:08
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.