-
Notifications
You must be signed in to change notification settings - Fork 0
/
RANDOM.ASM
93 lines (77 loc) · 2.11 KB
/
RANDOM.ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
; These algorithms come from the code in DLE.EXE.
;
; I presume they were part of the Random module in Turbo Pascal, but I
; am not sure.
;
; Of interest is that while this was built for 16-bit architecture, it
; uses a 32-bit seed in the form of two 16-bit words. Perhaps it used a
; 32-bit int type and this is just what operations on that type compiled
; down to.
;
; I think it more likely that the source was hand-written ASM.
;
; A key part of the algorithm seems to be the prime number 33,797
; (0x8405). Primes are often used to avoid math that tends towards
; certain patterns, although I'm sure there are patterns present in the
; data generated by this. Is it notable that it's a number that is
; slightly higher than (0xffff >> 1)? Maybe.
;
; Also, and maybe this is the pattern with psuedo-random generators, but
; it seems to function by mutating the seed and then the next_int
; function just riffs on that a bit given its input mask.
;
section .text
; Set a specific seed for the RNG
rng_seed:
push bp
mov bp,sp
mov ax,[bp+6]
mov [rng_seed_1],ax
mov ax,[bp+4]
mov [rng_seed_2],ax
pop bp
ret
; 1 input param: upper bound
; The returned value will be less than the number passed in.
rng_next_int:
push bp
mov bp,sp
call .rng_next_seed
mov cx,dx
mul word [bp+4]
mov ax,cx
mov cx,dx
mul word [bp+4]
add ax,cx
adc dx,0
mov ax,dx
mov sp,bp
pop bp
ret
; This here is why it's called a pseudo-random number generator.
; There's nothing random about this at all.
.rng_next_seed:
mov ax,[rng_seed_1]
mov bx,[rng_seed_2]
mov cx,ax
mul word [rng_const]
shl cx,3
add ch,cl
add dx,cx
add dx,bx
shl bx,2
add dx,bx
add dh,bl
shl bx,5
add dh,bl
add ax,1
adc dx,0
mov [rng_seed_1],ax
mov [rng_seed_2],dx
ret
section .bss
rng_seed_1 resw 1
rng_seed_2 resw 1
section .data
; This is a prime number: 33,797
rng_const dw 8405h