Random Int in Assembly x86

This article has been written before more than 24months, information might old.

In general crearea unui random int in lumea reala poate fi facuta prin mai multe metode insa cea mai comuna in lumea virtuala este folosind timpul , aceasta metoda este destul de criticata pentru ca desi se poate obtine un numar diferit intr-un interval nu se poate spune ca e aleator din moment ce e generat bazandu-se pe un numar care se schimba mereu .

Ideea este ca orice am folosi suntem nevoiti sa ne bazam pe un numar asa ca in definitiv un numar cu adevarat aleator nu exista . De aceea alte metode pot include algoritmi imensi pentru a genera secvente de numere care par aparent aleatorii dar atat timp cat se pleaca de la o valoare initiala numita samanta ( seed ) sau cheie ( key ) sunt de fapt pseudoaleatorii .

Dar in aplicatiile de zi cu zi exista multe situatii in care un pseudo numar aleator ne satisface nevoile .

Idea e ca pentru a crea un asa zis adevarat numar aleator trebuie creata o alta piesa hardware care sa extraga informatia dintr-un mediu real desi probabil ca si daca aceste conditii se indeplinesc , exista inca argumente sa ne gandim ca nu este cu adevarat aleator , daca ne gandim ca tot ce se intampla in mediul exterior se intampla in anumite limite , limite care nu pot fi cunoscute pentru ca nu au fost atinse si presupunem ca sunt infinite , dar in mai toate cazurile in natura inca nu s-a dovedit existenta infinitului . Eu personal consider ca nici creierul uman cand vrea sa genereze un numar aleator nu este cu adevarat aleator dar intram mai mult in filozofie deja .

Revenind la assembly pentru preluarea timpului vom folosi mnemonic-ul RDTSC ( disponibil pe orice procesor x86 ce are oppcode : 0F 31 ) , si care returneaza timpul in marime de 2 bytes sau 64 de biti in cei 2 registry EDX:EAX , byte-ul de ordine inalta se stocheaza EDX .

segment .data

segment .bss

segment .text
    global randint
randint:
    push ebp
    mov  ebp,esp
    mov  eax,[ebp+8]     
    cmp  eax,[ebp+12]
    jl   inorder
    xchg eax,[ebp+12]      
    mov  [ebp+8],eax
inorder:
    rdtsc
    shr  eax,2  
    mov  ebx,[ebp+12]     
    add  ebx,1            
    sub  ebx,[ebp+8]       
    cdq                   
    idiv ebx              
    add  edx,[ebp+8]

goback:
    mov  eax,edx
    mov  esp,ebp
    pop  ebp
    ret

Apoi pentru pentru folosirea obiectului produs de nasm , in c si in c++ se face diferit .
Si in anume functia importata extern se face diferit .

C++ :

#include <iostream>
extern "C" {int _cdecl randint(int, int);} 
using namespace std;
int main()
{
int a=1;int b=10;
cout << randint(a,b) ;
return  0;
}

C:

#include <stdio.h>
int randint(int low,int high);
int main()
{
int a = 1;
int b = 10;
printf("%d\n",randint(a,b));
return 1;
}

Compilarea putem sa o facem cu compilatorul cl din visual studio eu am folosit VS2010
este necesar sa setam variabilele de mediu ale windows-ului numite INCLUDE si LIB catre directoarele unde avem librariile statice .

Exemplul meu :

@set INCLUDE=D:\dev\apps\Microsoft Visual Studio 10.0\VC\include
@set LIB=D:\dev\apps\Microsoft Visual Studio 10.0\VC\lib;C:\Program Files\Microsoft SDKs\Windows\v7.0A\lib;
cl cpp.cpp randi.obj
Share the joy

Leave a Reply