flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
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: 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 |
|||
![]() |
|
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).
|
|||
![]() |
|
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 ![]() |
|||
![]() |
|
Enko 14 May 2011, 00:30
Overflowz wrote: Enko 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' 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. |
|||
![]() |
|
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 |
|||
![]() |
|
Overflowz 14 May 2011, 09:12
Enko
LocoDelAssembly Thank you for help! I got it now and works fine.. ![]() |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.