Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

random values

hi
i have coded a routine for random numbers. its nice, but slow
because of 'in al,40h'. if u have better code or algo please post.

here is my code for tasm:
[code]
model tiny,pascal
locals

.code
.386
org 100h
main:
mov ax,13h
int 10h
again:
CALL rand,offset X,0,319
CALL rand,offset Y,0,199
CALL randb,offset COL,0,255

CALL pix,0a000h,X,Y,word ptr COL


in al,60h
dec al
jnz again

mov ax,03h
int 10h
ret


;*****************************************************************************
; calculates a random- word- number. please do not request such funny *
; intervals like 0- 0 or 123- 123. *
; IN: ofsVAR = near pointer to a word in memory where the number should be *
; returned to. *
; min = the lowest value that might be returned *
; max = the highest value that might be returned *
;*****************************************************************************
rand proc near uses eax ebx edx di,ofsVAR,min,max : word
.386
xor eax,eax
xor ebx,ebx
xor edx,edx
mov ax,cs:[seed]
mov bx,cs:[seed]
xchg bh,bl
sub bx,cs:[seed]
mov bl,ah
mov ah,bh
xchg ah,al
in al,40h
add ax,cs:[seed]
xchg ah,al
mov cs:[seed],ax
mov bh,al
mov ax,bx
mov bx,[max]
sub bx,[min]
inc ebx
div ebx
mov di,[ofsVAR]
add dx,[min]
mov word ptr [di],dx
ret
.8086
seed dw 1234h
rand endp

;*****************************************************************************
; calculates a random- byte- number. please do not request such funny*
; intervals like 0- 0 or 123- 123. *
; IN: ofsVAR = near pointer to a byte in memory where the number should be *
; returned to. *
; min = the lowest value that might be returned *
; max = the highest value that might be returned *
;*****************************************************************************
randb proc near uses ax bx dx di,ofsVAR,min,max : word
inc [max]
mov ax,cs:[seed]
mov bx,cs:[seed]
xchg bh,bl
sub bx,cs:[seed]
mov bl,ah
mov ah,bh
xchg ah,al
in al,40h
sub ax,cs:[seed]
xchg ah,al
sub cs:[seed],ax
mov bh,al
mov ax,bx
mov bx,[max]
sub bx,[min]
xor dx,dx
div bx
mov di,[ofsVAR]
add dl,byte ptr [min]
mov byte ptr [di],dl
ret
randb endp

pix proc near uses ax bx es,SEGM,X1,Y1 : word, COL1 : word
.286
mov ax,[SEGM]
mov es,ax
mov ax,[Y1]
mov bx,[X1]
xchg ah,al
add bx,ax
shr ax,2
add bx,ax
mov al,byte ptr [COL1]
mov es:[bx],al
.8086
ret
pix endp


X dw ?
Y dw ?
COL db ?

end main
[/code]


Comments

  • blipblip Member Posts: 756
    I always use the timer port for random values, here's an elaborate version of it. Too bad it chokes the pipeline....

    [code]
    ;Input: Nothing
    ;Output: EAX=Random number
    ;Destroyed: DS, SI, EAX, ECX, EBX
    RandomNum PROC
    in al,40h
    mov ah,al
    in al,40h
    mov ds,ax
    shl eax,16
    in al,40h
    mov ah,al
    in al,40h
    mov ebx,eax
    mov si,ax
    mov dx,ax
    lds si,[si]
    in eax,dx
    xor eax,ebx
    xor eax,ecx
    xor eax,[si]
    ret
    RandomNum ENDP
    [/code]
  • angelusMortisangelusMortis Member Posts: 141
    : I always use the timer port for random values, here's an elaborate version of it. Too bad it chokes the pipeline....





    yea, i use the timer port either, but this is the problem. the port
    reading makes the procedure slow. this is why i'm looking for other
    solutions.
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [code]
    ; ----------------------------------------------------------------------------
    ; FILE: Random.Asm
    ; DATE: December 19, 2001
    ; DESCRIPTION: Random number generation.
    ; ----------------------------------------------------------------------------

    .386

    ; --- Includes:

    ; --- Externals:

    ; --- Publics:
    Public RandomRange
    Public Random
    Public RandomSeed
    Public Random1024

    ; ----------------------------------------------------------------------------
    Data Segment Use16 Dword Public 'DATA'
    Assume Ds:Data

    wNextRandom Dw 817
    wRandSeed Dw 0
    Data EndS

    ; ----------------------------------------------------------------------------
    Code Segment Use16 Dword Public 'CODE'
    Assume Cs:Code

    Random1024 Proc Near
    ; ----------------------------------------------------------------------------
    ; OUTPUT: AX -> random number in range [0..1023]
    ; ----------------------------------------------------------------------------
    push ecx
    push edx

    movzx eax, wNextRandom
    mov ecx, 217
    mul ecx
    add eax, 333
    mov ecx, 1024
    div ecx
    mov wNextRandom, dx
    mov ax, dx

    pop edx
    pop ecx
    ret
    Random1024 EndP

    ; ----------------------------------------------------------------------------
    RandomSeed Proc Near
    push ax
    push cx
    push dx

    mov ah, 2Ch
    int 21h
    xor dh, dl
    movzx cx, dh
    inc cx

    @_SeedInProgress:
    call Random1024
    loop @_SeedInProgress

    pop dx
    pop cx
    pop ax
    ret
    RandomSeed EndP

    Random Proc Near
    ; ----------------------------------------------------------------------------
    ; INPUT: DX <- enumerator value
    ; OUTPUT: AX -> random value in range [0..DX-1]
    ; ----------------------------------------------------------------------------
    push cx
    push dx

    call Random1024
    mov cx, dx
    xor dx, dx
    div cx
    mov ax, dx

    pop dx
    pop cx
    ret
    Random EndP

    RandomRange Proc Near
    ; ----------------------------------------------------------------------------
    ; INPUT:
    ; CX <- range begin
    ; DX <- range end
    ; OUTPUT:
    ; AX -> random value in range [CX..DX] inclusive
    ; ----------------------------------------------------------------------------
    push dx
    sub dx, cx
    inc dx
    call Random
    add ax, cx
    pop dx
    ret
    RandomRange EndP

    Code EndS
    End
    [/code]
  • PuzzlerPuzzler Member Posts: 208
    Well with huge ass rotuine like those, everything is bound to be slow. You might want to try optimizing your routines before worrying about simple problems like reading ports. Also, read about the RDTSC instruction. It is an almost undocumented instruction that reads the number of CPU clock cycles elapsed since start up.

    --------------------------------------------
    I will bend your mind with my spoon...

  • blipblip Member Posts: 756
    RDTSC is good for Pentium+'s, but not 486's and below. It and the PIT aren't really that random, that's why I'd also read random memory cells and ports and use XOR to randomize the number some more. Random number generation isn't used all that often anyway and people usually care more about good random number generation.
  • PuzzlerPuzzler Member Posts: 208
    [b][red]This message was edited by Puzzler at 2002-8-15 8:9:28[/red][/b][hr]
    Actually it is pretty good. In windows, its great because you never know how many cycles are stolen by the OS and other progs. For me it's good because I wait for the timer often in my little demo so it's pretty good. Also, it generates number based on when the program starts and therefore is dependent on the user. Besides, it's at elast good for a seed because there are no port reads, no memory reads, no loops, and no other slowdowns and it is only 2 bytes. Yoiu could use it in your prog by itself for a random number generator if you wanted to skip a 3 byte call, having a routine at the end of the program, and a lot of overhead for the call.

    Now to tell you, the problem with reading ports is that you might read a value off of a queue or stack and fubar a program.


    --------------------------------------------
    I will bend your mind with my spoon...



  • angelusMortisangelusMortis Member Posts: 141
    the port read IS the problem.
    i didn't try ur routine, but i dont think that its usefull in a loop
    cause it'll give me almost the same number on the next loop.
  • Shawn CarterShawn Carter Member Posts: 0

    ___ || http://forcoder.org || free ebooks and video tutorials about / C#, Visual Basic .NET, Perl, Visual Basic, JavaScript, Python, PL/SQL, Objective-C, Delphi, Scratch, Swift, C, MATLAB, R, PHP, Ruby, Go, Assembly, Java, C++ Transact-SQL, LabVIEW, Bash, Julia, Lua, F#, VBScript, Prolog, Fortran, Rust, Erlang, Alice, Awk, COBOL, Ada, Logo, Apex, ML, Dart, ABAP, D, Hack, SAS, Lisp, FoxPro, Scala, Kotlin, Crystal, Scheme, Clojure /

Sign In or Register to comment.