flat assembler
Message board for the users of flat assembler.

 Index > Main > Got error on division..
Author
Overflowz

Joined: 03 Sep 2010
Posts: 1046
Overflowz 13 May 2011, 21:24
Hello everyone, I found something for randomizing numbers but division fails and I don't know why.. can someone tell me what's problem here because I really don't understand.. BTW, it should generate random number from 1 to 6. Thanks.
Code:
```rdtsc ;Read Time Samp Counter
mov bx,6 ;for division, max number 6
div bx
inc dx ;start from 1, min number 1    ```
13 May 2011, 21:24
Enko

Joined: 03 Apr 2007
Posts: 676
Location: Mar del Plata
Enko 13 May 2011, 22:11
Overflowz wrote:
Hello everyone, I found something for randomizing numbers but division fails and I don't know why.. can someone tell me what's problem here because I really don't understand.. BTW, it should generate random number from 1 to 6. Thanks.
Code:
```rdtsc ;Read Time Samp Counter
mov bx,6 ;for division, max number 6
div bx
inc dx ;start from 1, min number 1    ```

Code:
```proc _RandInt;
; IN{ ->EAX Range } RANGE FROM 0 TO EAX - 1
; OUT{ <-EAX Result }
IMUL EDX,[RandSeed],08088405H
INC EDX
MOV RandSeed,EDX
MUL EDX
MOV EAX,EDX
RET
```

RandSeed is a globale variable, from where to start the random, could be any number in the range of int.
for initialization of RandSeed you can use the time stamp.

The routin is from Delphi VCL.

Last edited by Enko on 14 May 2011, 00:31; edited 2 times in total
13 May 2011, 22:11
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 13 May 2011, 22:19
The problem is that you forgot to clear DX before performing the division (DIV here divides DX:AX by 6, and if the quotient doesn't fit in AX then you get an exception).
13 May 2011, 22:19
Overflowz

Joined: 03 Sep 2010
Posts: 1046
Overflowz 13 May 2011, 23:58
Enko
Sorry, I don't understand Delphi..
LocoDelAssembly
isn't this true or I'm wrong ? EDX = 0x00000001 and EAX = 0x00000002 and ECX = 0x00000006 then div ecx = 0000000100000002/6 ? I still don't understand..
rdtsc stores 2 values in EAX and DX registers and after doing div cx which is 6, it fails.. Why I should clear DX I don't understand
13 May 2011, 23:58
Enko

Joined: 03 Apr 2007
Posts: 676
Location: Mar del Plata
Enko 14 May 2011, 00:30
Overflowz wrote:
Enko
Sorry, I don't understand Delphi..
LocoDelAssembly
isn't this true or I'm wrong ? EDX = 0x00000001 and EAX = 0x00000002 and ECX = 0x00000006 then div ecx = 0000000100000002/6 ? I still don't understand..
rdtsc stores 2 values in EAX and DX registers and after doing div cx which is 6, it fails.. Why I should clear DX I don't understand

What do you mean you dont undertand delphi? XD

the source I posted is writen in assembly.
well, delphy assembly but it quite similar xD

here goes a complete and functional example. pseudoRandom numbers from 0 to 5;
Code:
```
format PE Console
entry start

include 'D:\Fasm\INCLUDE\win32a.inc'
include 'D:\Fasm\INCLUDE\macro/if.inc'

szInt db  '%i',10,13, 0
RandSeed  dd   0;
szPause  db 'PAUSE',0

start:
;set the rand seed to some value...
invoke GetTickCount
mov  [RandSeed], eax

xor esi, esi
.while esi <=50
stdcall _RandInt, 6
cinvoke printf, szInt, eax; the result of random is in eax
inc esi
.endw
invoke  system, szPause
invoke  ExitProcess,0

proc _RandInt, range
; OUT{ <-EAX Result }
MOV  EAX, [range]
IMUL EDX,[RandSeed],08088405H
INC EDX
MOV [RandSeed],EDX
MUL EDX
MOV EAX,EDX
ret

endp

section '.idata' import data readable writeable

library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL',\
msvcrt,'msvcrt.dll'

include 'D:\Fasm\INCLUDE\api\kernel32.inc'
include 'D:\Fasm\INCLUDE\api\user32.inc'
include 'D:\Fasm\INCLUDE\api\msvcrt.inc'
```

if you dont have the standart c library include file (mvscrt.inc) you can download it from here:
its atached with an old project a wrote.
14 May 2011, 00:30
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 14 May 2011, 01:58
Overflowz, first please define the width of the divisor, since it is different if you use CL, CX, ECX or RCX (the latter available only in 64-bit mode) as it operates on different registers:

8-bit divisor (CL): AL = ((AH * 2^8) + AL) div CL; AH = ((AH * 2^8) + AL) mod CL
16-bit divisor (CX): AX = ((DX * 2^16) + AX) div CX; DX = ((DX * 2^16) + AX) mod CX
32-bit divisor (ECX): EAX = ((EDX * 2^32) + EAX) div ECX; EDX = ((EDX * 2^32) + EAX) mod ECX
64-bit divisor (RCX): RAX = ((RDX * 2^64) + RAX) div RCX; RDX = ((RDX * 2^64) + RAX) mod RCX

Now, the problem is that AL can hold values in the [0..2^8] range, AX in the [0..2^16] range, EAX in the [0..2^32] range and RAX in the [0..2^64] range, so if AH/DX/EDX/RDX isn't cleared (i.e. zero), besides the fact that you probably wanted to divide the value in AL/AX/EAX/RAX only, you also risk for a divide error since the quotient may turn out to be too big to fit in AL/AX/EAX/RAX.

If you really want to apply the division to the full time stamp, then use a long division method like the following:
Code:
```rdtsc
mov ebx, eax ; Save copy of low part

mov ecx, 6 ; Divisor
; EDX:EAX = Dividend
; Divide high part first (EDX)
mov eax, edx
xor edx, edx
div ecx
; Now low part, using the previous reminder as the high "digits" of the dividend ([EDX MOD 6]:EAX)
mov eax, ebx
div ecx

; EDX = Holds a value in the [0..5] range here    ```
14 May 2011, 01:58
Overflowz

Joined: 03 Sep 2010
Posts: 1046
Overflowz 14 May 2011, 09:12
Enko
LocoDelAssembly
Thank you for help! I got it now and works fine..
14 May 2011, 09:12
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainTutorials and ExamplesDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsOS ConstructionIDE DevelopmentProjects and IdeasNon-x86 architecturesHigh Level LanguagesProgramming Language DesignCompiler Internals Other----------------FeedbackHeapTest Area

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum