flat assembler
Message board for the users of flat assembler.

Index > Main > Got error on division..

Author
Thread Post new topic Reply to topic
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    
Post 13 May 2011, 21:24
View user's profile Send private message Reply with quote
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
Post 13 May 2011, 22:11
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


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).
Post 13 May 2011, 22:19
View user's profile Send private message Reply with quote
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 Sad
Post 13 May 2011, 23:58
View user's profile Send private message Reply with quote
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 Sad

What do you mean you dont undertand delphi? XD

the source I posted is writen in assembly. Rolling Eyes Rolling Eyes Rolling Eyes Rolling Eyes
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'



section '.data' data readable writeable 
szInt db  '%i',10,13, 0
RandSeed  dd   0;
szPause  db 'PAUSE',0
     
    
    
section '.code' code readable executable 
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:
http://board.flatassembler.net/download.php?id=4028
its atached with an old project a wrote.
Post 14 May 2011, 00:30
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


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    
Post 14 May 2011, 01:58
View user's profile Send private message Reply with quote
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.. Smile
Post 14 May 2011, 09:12
View user's profile Send private message 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-2023, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.