Начало...
Рассмотрим работу функции для вещественных (дробных) чисел.
function Random3: extended;
const two2neg32 = 1/$100000000; // 2^-32
var z: int64;
begin
RandSeed:=RandSeed*$8088405 + 1;
z:=RandSeed;
if z<0 then
z:=z+$100000000;
Result:=z*two2neg32;
end;
Примечание 1. Допускается перегружать процедуры и
функции с одинаковыми именами, дописав слово overload :
function Random1: extended; overload;
Примечание 2. Константа two2neg32
равна 0,00000000023283064365386962890625
(2 в степени -32).
Рассмотрим пример образования последовательности вещественных чисел в диапазоне
от 0 до 1. Процедуру Randomize вызывать не будем
(RandSeed = 0 ). Последовательность чисел будем вызывать с помощью
функций Random3 и Random (для проверки).
procedure TForm1.Button2Click(Sender: TObject);
const rs = 0;
var i: integer;
a: real;
begin
Memo1.Clear;
RandSeed:=rs;
for i:=1 to 30 do
begin
a:=Random;
Memo1.Lines.Add(Format('%d число = %g, RandSeed = %d', [i, a, RandSeed]));
end;
Memo2.Clear;
RandSeed:=rs;
for i:=1 to 30 do
begin
a:=Random3;
Memo2.Lines.Add(Format('%d число = %g, RandSeed = %d', [i, a, RandSeed]));
end;
end;
Тексты в Memo1 и Memo2 будут выглядеть одинаково:
1 число = 2,3283064365387E-10, RandSeed = 1
2 число = 0,0313799395225942, RandSeed = 134775814
3 число = 0,861048467224464, RandSeed = -596792289
4 число = 0,202580965124071, RandSeed = 870078620
5 число = 0,272921267198399, RandSeed = 1172187917
6 число = 0,671654418576509, RandSeed = -1410233534
7 число = 0,318691271124408, RandSeed = 1368768587
8 число = 0,161795465275645, RandSeed = 694906232
9 число = 0,372238358715549, RandSeed = 1598751577
10 число = 0,425673767458647, RandSeed = 1828254910
11 число = 0,0820121595170349, RandSeed = 352239543
12 число = 0,474794064648449, RandSeed = 2039224980
13 число = 0,0705693301279098, RandSeed = 303092965
14 число = 0,84085443476215, RandSeed = -683524998
15 число = 0,0597242347430438, RandSeed = 256513635
16 число = 0,293296571820974, RandSeed = 1259699184
17 число = 0,917284708702937, RandSeed = -355259471
18 число = 0,367906478699297, RandSeed = 1580146294
19 число = 0,774664897238836, RandSeed = -967806897
20 число = 0,327925535850227, RandSeed = 1408429452
21 число = 0,697674974100664, RandSeed = -1298476099
22 число = 0,844170969445258, RandSeed = -669280590
23 число = 0,717982857255265, RandSeed = -1211254405
24 число = 0,306641304865479, RandSeed = 1317014376
25 число = 0,162625851342455, RandSeed = 698472713
26 число = 0,329496453981847, RandSeed = 1415176494
27 число = 0,46602045907639, RandSeed = 2001542631
28 число = 0,24665364716202, RandSeed = 1059369348
29 число = 0,825676416279748, RandSeed = -748714091
30 число = 0,279029483441263, RandSeed = 1198422506
Таким образом, при неоднократном вызове Random функция выдаст
последовательность чисел: 2,3283064365387E-10,
0,0313799395225942, 0,861048467224464, 0,202580965124071, 0,272921267198399,
0,671654418576509, 0,318691271124408, 0,161795465275645, 0,372238358715549,
0,425673767458647, 0,0820121595170349, 0,474794064648449, 0,0705693301279098,
0,84085443476215, 0,0597242347430438, 0,293296571820974 и т.д.
Рассмотрим подробно образование случайных чисел. Вычисления проведем в таблице.
Число |
Код (команда) |
Значение z |
Значение RandSeed |
Значение Result |
Подробное вычисление |
Исходные данные: RandSeed = 0; постоянная two2neg32
= 0,00000000023283064365386962890625 = 2-32 |
1 |
RandSeed:=RandSeed*$8088405 + 1; |
0 |
1 |
0 |
RandSeed = RandSeed * $8088405 + 1 = 0 * 134775813 + 1 = 1 |
z:=RandSeed; |
1 |
1 |
0 |
z = RandSeed = 1 |
if z<0 then z:=z+$100000000; |
< не выполняется > |
Result:=z*two2neg32; |
1 |
1 |
2,3283064365387E-10 |
Result = z * two2neg32 = 1 * 2-32 = 2,3283064365387 * 10-10 |
Вывод: 1 число = 2,3283064365387E-10, RandSeed = 1 |
2 |
RandSeed:=RandSeed*$8088405 + 1; |
0 |
134775814 |
0 |
RandSeed = RandSeed * $8088405 + 1 = 1 * 134775813 + 1 = 134775814 |
z:=RandSeed; |
134775814 |
134775814 |
0 |
z = RandSeed = 134775814 |
if z<0 then z:=z+$100000000; |
< не выполняется > |
Result:=z*two2neg32; |
134775814 |
134775814 |
0,0313799395225942 |
Result = z * two2neg32 = 134775814 * 2-32 = 0,0313799395225942 |
Вывод: 2 число = 0,0313799395225942, RandSeed = 134775814 |
3 |
RandSeed:=RandSeed*$8088405 + 1; |
0 |
-596792289 |
0 |
RandSeed = RandSeed * $8088405 + 1 = 134775814 * 134775813 + 1 =
18164519904586783 ($408888DC6DAC1F) |
Примечание. Поскольку тип Integer принимает
значения -2147483648..2147483647, занимает 4 байта, то в памяти
компьютера произойдет переполнение: 18164519904586783 > 2147483647.
В этом случае, в переменную RandSeed запишется только 4 младших байта
($DC6DAC1F), а остальную часть ($408888) отбросит. Т.к. число $DC6DAC1F
= 3698175007 > 2147483647, в этом случае переменная RandSeed примет
отрицательное значение: -596792289. |
z:=RandSeed; |
-596792289 |
-596792289 |
0 |
z = RandSeed = -596792289 |
if z<0 then z:=z+$100000000; |
3698175007 |
-596792289 |
0 |
if -596792289<0 then z = -596792289 + 4294967296 = 3698175007 |
Примечание. Размер переменной z составляет 8 байт
(тип Int64), поэтому для корректной работы необходимо положительное
значение, добавив небольшое условие. |
Result:=z*two2neg32; |
3698175007 |
-596792289 |
0,861048467224464 |
Result = z * two2neg32 = 3698175007 * 2-32 = 0,861048467224464 |
Вывод: 3 число = 0,861048467224464, RandSeed = -596792289 |
4 |
RandSeed:=RandSeed*$8088405 + 1; |
0 |
870078620 |
0 |
RandSeed = RandSeed * $8088405 + 1 = -596792289 * 134775813 + 1 =
<для корректной работы -596792289 заменим на 3698175007> =
3698175007 * 134775813 + 1 = 498424543184705692
($6EAC27B33DC589C) |
z:=RandSeed; |
870078620 |
870078620 |
0 |
z = RandSeed = 870078620 |
if z<0 then z:=z+$100000000; |
< не выполняется > |
Result:=z*two2neg32; |
870078620 |
870078620 |
0,202580965124071 |
Result = z * two2neg32 = 870078620 * 2-32 = 0,202580965124071 |
Вывод: 4 число = 0,202580965124071, RandSeed = 870078620 |
5 |
RandSeed:=RandSeed*$8088405 + 1; |
0 |
1172187917 |
0 |
RandSeed = RandSeed * $8088405 + 1 = 870078620 * 134775813 + 1 =
117265553384418061
($1A09C6645DE2B0D) |
z:=RandSeed; |
1172187917 |
1172187917 |
0 |
z = RandSeed = 1172187917 |
if z<0 then z:=z+$100000000; |
< не выполняется > |
Result:=z*two2neg32; |
1172187917 |
1172187917 |
0,272921267198399 |
Result = z * two2neg32 = 1172187917 * 2-32 = 0,272921267198399 |
Вывод: 5 число = 0,272921267198399, RandSeed = 1172187917 |
Далее аналогичным образом рассчитываются следующие числа.
Рассмотрим следующую функцию, написанную на ассемблере.
function Random4: extended;
const two2neg32: double = 1/$100000000; // 2^-32
asm
IMUL EDX, RandSeed, $8088405
INC EDX
MOV RandSeed, EDX
FLD QWORD PTR two2neg32
PUSH $0
PUSH EDX
FILD QWORD PTR [ESP]
ADD ESP, $4
POP EDX
FMULP
FSTP TBYTE PTR Result
end;
Комментарии:
IMUL EDX, RandSeed, $8088405 – умножает RandSeed
на $8088405 и записывает в регистр EDX ;
INC EDX – увеличивает значение регистра EDX на
единицу;
MOV RandSeed, EDX – присваивает переменной
RandSeed значение регистра EDX ;
FLD QWORD PTR two2neg32 – загружает 64-разрядное вещественное
число two2neg32 в ST(0) (вершину стека сопроцессора);
PUSH $0 – размещает значение "0" в стеке, т.е. помещает
значение в ячейку памяти, на которую указывает регистр ESP , после
этого значение регистра ESP уменьшается на 4;
PUSH EDX – размещает значение регистра EDX в
стеке;
FILD QWORD PTR [ESP] – загружает 64-разрядное целое число в
регистр ST(0) (вершину стека сопроцессора) из области памяти по
адресу ESP , при загрузке какого-либо значения в стек сопроцессора
все значения стека сдвигаются, т.е. значение регистра ST(0) загрузит
в ST(1) , а наше новое значение загружается в ST(0) ;
ADD ESP, $4 – увеличивает значение регистра ESP
на 4;
POP EDX – извлекает значение из стека, т.е. извлекает
значение из ячейки памяти, на которую указывает регистр ESP , и
сохраняет в регистре EDX , после этого увеличивает значение регистра
ESP на 4;
FMULP – умножение значений регистра ST(0)
сопроцессора на ST(1) и выталкивание из стека (значение в
ST(1) будет Empty /нет данных/), результат записывается
в ST(0) ;
FSTP TBYTE PTR Result – записывает 80-разрядное вещественное
число из регистра ST(0) в переменную Result , при этом
происходит выталкивание вершины из стека сопроцессора (ST(0) = Empty ).
Рассмотрим пример образования последовательности вещественных чисел в диапазоне
от 0 до 1. Процедуру Randomize вызывать не будем
(RandSeed = 0 ). Последовательность чисел будем вызывать с помощью
функций Random4 и Random (для проверки).
В процедуре TForm1.Button2Click в коде заменим функцию
Random3 на Random4 .
procedure TForm1.Button2Click(Sender: TObject);
const rs = 0;
var i: integer;
a: real;
begin
Memo1.Clear;
RandSeed:=rs;
for i:=1 to 30 do
begin
a:=Random;
Memo1.Lines.Add(Format('%d число = %g, RandSeed = %d', [i, a, RandSeed]));
end;
Memo2.Clear;
RandSeed:=rs;
for i:=1 to 30 do
begin
a:=Random4;
Memo2.Lines.Add(Format('%d число = %g, RandSeed = %d', [i, a, RandSeed]));
end;
end;
Тексты в Memo1 и Memo2 будут выглядеть одинаково:
1 число = 2,3283064365387E-10, RandSeed = 1
2 число = 0,0313799395225942, RandSeed = 134775814
3 число = 0,861048467224464, RandSeed = -596792289
4 число = 0,202580965124071, RandSeed = 870078620
5 число = 0,272921267198399, RandSeed = 1172187917
6 число = 0,671654418576509, RandSeed = -1410233534
7 число = 0,318691271124408, RandSeed = 1368768587
8 число = 0,161795465275645, RandSeed = 694906232
9 число = 0,372238358715549, RandSeed = 1598751577
10 число = 0,425673767458647, RandSeed = 1828254910
11 число = 0,0820121595170349, RandSeed = 352239543
12 число = 0,474794064648449, RandSeed = 2039224980
13 число = 0,0705693301279098, RandSeed = 303092965
14 число = 0,84085443476215, RandSeed = -683524998
15 число = 0,0597242347430438, RandSeed = 256513635
16 число = 0,293296571820974, RandSeed = 1259699184
17 число = 0,917284708702937, RandSeed = -355259471
18 число = 0,367906478699297, RandSeed = 1580146294
19 число = 0,774664897238836, RandSeed = -967806897
20 число = 0,327925535850227, RandSeed = 1408429452
21 число = 0,697674974100664, RandSeed = -1298476099
22 число = 0,844170969445258, RandSeed = -669280590
23 число = 0,717982857255265, RandSeed = -1211254405
24 число = 0,306641304865479, RandSeed = 1317014376
25 число = 0,162625851342455, RandSeed = 698472713
26 число = 0,329496453981847, RandSeed = 1415176494
27 число = 0,46602045907639, RandSeed = 2001542631
28 число = 0,24665364716202, RandSeed = 1059369348
29 число = 0,825676416279748, RandSeed = -748714091
30 число = 0,279029483441263, RandSeed = 1198422506
Таким образом, при неоднократном вызове Random функция выдаст
последовательность чисел: 2,3283064365387E-10,
0,0313799395225942, 0,861048467224464, 0,202580965124071, 0,272921267198399,
0,671654418576509, 0,318691271124408, 0,161795465275645, 0,372238358715549,
0,425673767458647, 0,0820121595170349, 0,474794064648449, 0,0705693301279098,
0,84085443476215, 0,0597242347430438, 0,293296571820974 и т.д.
Рассмотрим подробно образование случайных чисел. Вычисления проведем в таблице.
Число |
Код (команда) |
Значение регистра EDX |
Значение регистра ESP |
Стек |
Сопроцессор |
Значение RandSeed |
Значение Result |
Подробное вычисление |
Исходные данные: RandSeed = 0; постоянная two2neg32
= 0,00000000023283064365386962890625 = 2-32 |
1 |
IMUL EDX, RandSeed, $8088405 |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = Empty |
0 |
0 |
EDX = RandSeed * $8088405 = 0 * 134775813 = 0 ($0) |
Примечание. В регистры будем записывать только
шестнадцатеричные значения, а в скобках - десятичные. |
INC EDX |
$00000001 (1) |
$0018F2C8 |
- |
ST0 = Empty |
0 |
0 |
EDX = EDX + 1 = 0 + 1 = 1 ($1) |
MOV RandSeed, EDX |
$00000001 (1) |
$0018F2C8 |
- |
ST0 = Empty |
$1 (1) |
0 |
RandSeed = EDX = 1 ($1) |
FLD QWORD PTR two2neg32 |
$00000001 (1) |
$0018F2C8 |
- |
ST0 = 2,3283064365387E-10
ST1 = Empty |
$1 (1) |
0 |
ST(0) = two2neg32 = 2-32 = 2,3283064365387 * 10-10 |
PUSH $0 |
$00000001 (1) |
$0018F2C4 |
$0018F2C4: $00000000 (0) |
ST0 = 2,3283064365387E-10 ST1 = Empty |
$1 (1) |
0 |
ESP = ESP - $4 = $18F2C8 - $4 = $18F2C4 [ESP] = [$18F2C4] = 0 ($0) |
PUSH EDX |
$00000001 (1) |
$0018F2C0 |
$0018F2C4: $00000000 (0)
$0018F2C0: $00000001 (1) |
ST0 = 2,3283064365387E-10 ST1 = Empty |
$1 (1) |
0 |
ESP = ESP - $4 = $18F2C4 - $4 = $18F2C0
[ESP] = [$18F2C0] = EDX = 1 ($1) |
FILD QWORD PTR [ESP] |
$00000001 (1) |
$0018F2C0 |
$0018F2C4: $00000000 (0) $0018F2C0: $00000001 (1) |
ST0 = 1
ST1 = 2,3283064365387E-10 ST2 = Empty |
$1 (1) |
0 |
ST(1) = ST(0) = 2,3283064365387 * 10-10
ST(0) = [ESP] = [$18F2C0] = 1 |
ADD ESP, $4 |
$00000001 (1) |
$0018F2C4 |
$0018F2C4: $00000000 (0) |
ST0 = 1 ST1 = 2,3283064365387E-10 ST2 = Empty |
$1 (1) |
0 |
ESP = ESP + $4 = $18F2C0 + $4 = $18F2C4 |
POP EDX |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = 1 ST1 = 2,3283064365387E-10 ST2 = Empty |
$1 (1) |
0 |
EDX = [ESP] = [$18F2C0] = 0 ($0)
ESP = ESP + $4 = $18F2C4 + $4 = $18F2C8 |
FMULP |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = 2,3283064365387E-10 ST1 = Empty |
$1 (1) |
0 |
ST(0) = ST(0) * ST(1) = 1 * 2,3283064365387 * 10-10 =
2,3283064365387 * 10-10 |
FSTP TBYTE PTR Result |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = Empty |
$1 (1) |
2,3283064365387E-10 |
Result = ST(0) = 2,3283064365387 * 10-10 |
Вывод: 1 число = 2,3283064365387E-10, RandSeed = 1 |
2 |
IMUL EDX, RandSeed, $8088405 |
$08088405 (134775813) |
$0018F2C8 |
- |
ST0 = Empty |
$1 (1) |
0 |
EDX = RandSeed * $8088405 = 1 * 134775813 = 134775813 ($8088405) |
INC EDX |
$08088406 (134775814) |
$0018F2C8 |
- |
ST0 = Empty |
$1 (1) |
0 |
EDX = EDX + 1 = 134775813 + 1 = 134775814 ($8088406) |
MOV RandSeed, EDX |
$08088406 (134775814) |
$0018F2C8 |
- |
ST0 = Empty |
$8088406 (134775814) |
0 |
RandSeed = EDX = 134775814 ($8088406) |
FLD QWORD PTR two2neg32 |
$08088406 (134775814) |
$0018F2C8 |
- |
ST0 = 2,3283064365387E-10
ST1 = Empty |
$8088406 (134775814) |
0 |
ST(0) = two2neg32 = 2-32 = 2,3283064365387 * 10-10 |
PUSH $0 |
$08088406 (134775814) |
$0018F2C4 |
$0018F2C4: $00000000 (0) |
ST0 = 2,3283064365387E-10 ST1 = Empty |
$8088406 (134775814) |
0 |
ESP = ESP - $4 = $18F2C8 - $4 = $18F2C4 [ESP] = [$18F2C4] = 0 ($0) |
PUSH EDX |
$08088406 (134775814) |
$0018F2C0 |
$0018F2C4: $00000000 (0)
$0018F2C0: $8088406 (134775814) |
ST0 = 2,3283064365387E-10 ST1 = Empty |
$8088406 (134775814) |
0 |
ESP = ESP - $4 = $18F2C4 - $4 = $18F2C0
[ESP] = [$18F2C0] = EDX = 134775814 ($8088406) |
FILD QWORD PTR [ESP] |
$08088406 (134775814) |
$0018F2C0 |
$0018F2C4: $00000000 (0) $0018F2C0: $8088406 (134775814) |
ST0 = 134775814
ST1 = 2,3283064365387E-10 ST2 = Empty |
$8088406 (134775814) |
0 |
ST(1) = ST(0) = 2,3283064365387 * 10-10
ST(0) = [ESP] = [$18F2C0] = 134775814 |
ADD ESP, $4 |
$08088406 (134775814) |
$0018F2C4 |
$0018F2C4: $00000000 (0) |
ST0 = 134775814 ST1 = 2,3283064365387E-10 ST2 = Empty |
$8088406 (134775814) |
0 |
ESP = ESP + $4 = $18F2C0 + $4 = $18F2C4 |
POP EDX |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = 134775814 ST1 = 2,3283064365387E-10 ST2 = Empty |
$8088406 (134775814) |
0 |
EDX = [ESP] = [$18F2C0] = 0 ($0)
ESP = ESP + $4 = $18F2C4 + $4 = $18F2C8 |
FMULP |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = 0,0313799395225942 ST1 = Empty |
$8088406 (134775814) |
0 |
ST(0) = ST(0) * ST(1) = 134775814 * 2,3283064365387 * 10-10 =
0,0313799395225942 |
FSTP TBYTE PTR Result |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = Empty |
$8088406 (134775814) |
0,0313799395225942 |
Result = ST(0) = 0,0313799395225942 |
Вывод: 2 число = 0,0313799395225942, RandSeed = 134775814 |
3 |
IMUL EDX, RandSeed, $8088405 |
$DC6DAC1E (3698175006) |
$0018F2C8 |
- |
ST0 = Empty |
$8088406 (134775814) |
0 |
EDX = RandSeed * $8088405 = 134775814 * 134775813 = 18164519904586782
($408888DC6DAC1E) |
Примечание. Старшее слово ($408888) нигде не
записывается (оно не учитывается). В регистр EDX записываются только
младшие разряды шестнадцатеричного числа. |
INC EDX |
$DC6DAC1F (3698175007) |
$0018F2C8 |
- |
ST0 = Empty |
$8088406 (134775814) |
0 |
EDX = EDX + 1 = 3698175006 + 1 = 3698175007 ($DC6DAC1F) |
MOV RandSeed, EDX |
$DC6DAC1F (3698175007) |
$0018F2C8 |
- |
ST0 = Empty |
$DC6DAC1F (-596792289) |
0 |
RandSeed = EDX = -596792289 ($DC6DAC1F) |
Примечание. Поскольку тип Integer принимает
значения -2147483648..2147483647, то число будет занимать 4 байта. Т.к.
число $DC6DAC1F = 3698175007 > 2147483647, в этом случае переменная
RandSeed примет отрицательное значение: -596792289. |
FLD QWORD PTR two2neg32 |
$DC6DAC1F (3698175007) |
$0018F2C8 |
- |
ST0 = 2,3283064365387E-10
ST1 = Empty |
$DC6DAC1F (-596792289) |
0 |
ST(0) = two2neg32 = 2-32 = 2,3283064365387 * 10-10 |
PUSH $0 |
$DC6DAC1F (3698175007) |
$0018F2C4 |
$0018F2C4: $00000000 (0) |
ST0 = 2,3283064365387E-10 ST1 = Empty |
$DC6DAC1F (-596792289) |
0 |
ESP = ESP - $4 = $18F2C8 - $4 = $18F2C4 [ESP] = [$18F2C4] = 0 ($0) |
PUSH EDX |
$DC6DAC1F (3698175007) |
$0018F2C0 |
$0018F2C4: $00000000 (0)
$0018F2C0: $DC6DAC1F (3698175007) |
ST0 = 2,3283064365387E-10 ST1 = Empty |
$DC6DAC1F (-596792289) |
0 |
ESP = ESP - $4 = $18F2C4 - $4 = $18F2C0
[ESP] = [$18F2C0] = EDX = 3698175007 ($DC6DAC1F) |
FILD QWORD PTR [ESP] |
$DC6DAC1F (3698175007) |
$0018F2C0 |
$0018F2C4: $00000000 (0) $0018F2C0: $DC6DAC1F (3698175007) |
ST0 = 3698175007
ST1 = 2,3283064365387E-10 ST2 = Empty |
$DC6DAC1F (-596792289) |
0 |
ST(1) = ST(0) = 2,3283064365387 * 10-10
ST(0) = [ESP] = [$18F2C0] = 3698175007 |
ADD ESP, $4 |
$DC6DAC1F (3698175007) |
$0018F2C4 |
$0018F2C4: $00000000 (0) |
ST0 = 3698175007 ST1 = 2,3283064365387E-10 ST2 = Empty |
$DC6DAC1F (-596792289) |
0 |
ESP = ESP + $4 = $18F2C0 + $4 = $18F2C4 |
POP EDX |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = 3698175007 ST1 = 2,3283064365387E-10 ST2 = Empty |
$DC6DAC1F (-596792289) |
0 |
EDX = [ESP] = [$18F2C0] = 0 ($0)
ESP = ESP + $4 = $18F2C4 + $4 = $18F2C8 |
FMULP |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = 0,861048467224464 ST1 = Empty |
$DC6DAC1F (-596792289) |
0 |
ST(0) = ST(0) * ST(1) = 3698175007 * 2,3283064365387 * 10-10 =
0,861048467224464 |
FSTP TBYTE PTR Result |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = Empty |
$DC6DAC1F (-596792289) |
0,861048467224464 |
Result = ST(0) = 0,861048467224464 |
Вывод: 3 число = 0,861048467224464, RandSeed = -596792289 |
4 |
IMUL EDX, RandSeed, $8088405 |
$33DC589B (870078619) |
$0018F2C8 |
- |
ST0 = Empty |
$DC6DAC1F (-596792289) |
0 |
EDX = RandSeed * $8088405 = -596792289 * 134775813 = <для
корректной работы -596792289 заменим на 3698175007> = 3698175007 *
134775813 = 498424543184705691
($6EAC27B33DC589B) |
INC EDX |
$33DC589C (870078620) |
$0018F2C8 |
- |
ST0 = Empty |
$DC6DAC1F (-596792289) |
0 |
EDX = EDX + 1 = 870078619 + 1 = 870078620 ($33DC589C) |
MOV RandSeed, EDX |
$33DC589C (870078620) |
$0018F2C8 |
- |
ST0 = Empty |
$33DC589C (870078620) |
0 |
RandSeed = EDX = 870078620 ($33DC589C) |
FLD QWORD PTR two2neg32 |
$33DC589C (870078620) |
$0018F2C8 |
- |
ST0 = 2,3283064365387E-10
ST1 = Empty |
$33DC589C (870078620) |
0 |
ST(0) = two2neg32 = 2-32 = 2,3283064365387 * 10-10 |
PUSH $0 |
$33DC589C (870078620) |
$0018F2C4 |
$0018F2C4: $00000000 (0) |
ST0 = 2,3283064365387E-10 ST1 = Empty |
$33DC589C (870078620) |
0 |
ESP = ESP - $4 = $18F2C8 - $4 = $18F2C4 [ESP] = [$18F2C4] = 0 ($0) |
PUSH EDX |
$33DC589C (870078620) |
$0018F2C0 |
$0018F2C4: $00000000 (0)
$0018F2C0: $33DC589C (870078620) |
ST0 = 2,3283064365387E-10 ST1 = Empty |
$33DC589C (870078620) |
0 |
ESP = ESP - $4 = $18F2C4 - $4 = $18F2C0
[ESP] = [$18F2C0] = EDX = 870078620 ($33DC589C) |
FILD QWORD PTR [ESP] |
$33DC589C (870078620) |
$0018F2C0 |
$0018F2C4: $00000000 (0) $0018F2C0: $33DC589C (870078620) |
ST0 = 870078620
ST1 = 2,3283064365387E-10 ST2 = Empty |
$33DC589C (870078620) |
0 |
ST(1) = ST(0) = 2,3283064365387 * 10-10
ST(0) = [ESP] = [$18F2C0] = 870078620 |
ADD ESP, $4 |
$33DC589C (870078620) |
$0018F2C4 |
$0018F2C4: $00000000 (0) |
ST0 = 870078620 ST1 = 2,3283064365387E-10 ST2 = Empty |
$33DC589C (870078620) |
0 |
ESP = ESP + $4 = $18F2C0 + $4 = $18F2C4 |
POP EDX |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = 870078620 ST1 = 2,3283064365387E-10 ST2 = Empty |
$33DC589C (870078620) |
0 |
EDX = [ESP] = [$18F2C0] = 0 ($0)
ESP = ESP + $4 = $18F2C4 + $4 = $18F2C8 |
FMULP |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = 0,202580965124071 ST1 = Empty |
$33DC589C (870078620) |
0 |
ST(0) = ST(0) * ST(1) = 870078620 * 2,3283064365387 * 10-10 =
0,202580965124071 |
FSTP TBYTE PTR Result |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = Empty |
$33DC589C (870078620) |
0,202580965124071 |
Result = ST(0) = 0,202580965124071 |
Вывод: 4 число = 0,202580965124071, RandSeed = 870078620 |
5 |
IMUL EDX, RandSeed, $8088405 |
$45DE2B0C (1172187916) |
$0018F2C8 |
- |
ST0 = Empty |
$33DC589C (870078620) |
0 |
EDX = RandSeed * $8088405 = 870078620 * 134775813 = 117265553384418060
($1A09C6645DE2B0C) |
INC EDX |
$45DE2B0D (1172187917) |
$0018F2C8 |
- |
ST0 = Empty |
$33DC589C (870078620) |
0 |
EDX = EDX + 1 = 1172187916 + 1 = 1172187917 ($45DE2B0D) |
MOV RandSeed, EDX |
$45DE2B0D (1172187917) |
$0018F2C8 |
- |
ST0 = Empty |
$45DE2B0D (1172187917) |
0 |
RandSeed = EDX = 1172187917 ($45DE2B0D) |
FLD QWORD PTR two2neg32 |
$45DE2B0D (1172187917) |
$0018F2C8 |
- |
ST0 = 2,3283064365387E-10
ST1 = Empty |
$45DE2B0D (1172187917) |
0 |
ST(0) = two2neg32 = 2-32 = 2,3283064365387 * 10-10 |
PUSH $0 |
$45DE2B0D (1172187917) |
$0018F2C4 |
$0018F2C4: $00000000 (0) |
ST0 = 2,3283064365387E-10 ST1 = Empty |
$45DE2B0D (1172187917) |
0 |
ESP = ESP - $4 = $18F2C8 - $4 = $18F2C4 [ESP] = [$18F2C4] = 0 ($0) |
PUSH EDX |
$45DE2B0D (1172187917) |
$0018F2C0 |
$0018F2C4: $00000000 (0)
$0018F2C0: $45DE2B0D (1172187917) |
ST0 = 2,3283064365387E-10 ST1 = Empty |
$45DE2B0D (1172187917) |
0 |
ESP = ESP - $4 = $18F2C4 - $4 = $18F2C0
[ESP] = [$18F2C0] = EDX = 1172187917 ($45DE2B0D) |
FILD QWORD PTR [ESP] |
$45DE2B0D (1172187917) |
$0018F2C0 |
$0018F2C4: $00000000 (0) $0018F2C0: $45DE2B0D (1172187917) |
ST0 = 1172187917
ST1 = 2,3283064365387E-10 ST2 = Empty |
$45DE2B0D (1172187917) |
0 |
ST(1) = ST(0) = 2,3283064365387 * 10-10
ST(0) = [ESP] = [$18F2C0] = 1172187917 |
ADD ESP, $4 |
$45DE2B0D (1172187917) |
$0018F2C4 |
$0018F2C4: $00000000 (0) |
ST0 = 1172187917 ST1 = 2,3283064365387E-10 ST2 = Empty |
$45DE2B0D (1172187917) |
0 |
ESP = ESP + $4 = $18F2C0 + $4 = $18F2C4 |
POP EDX |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = 1172187917 ST1 = 2,3283064365387E-10 ST2 = Empty |
$45DE2B0D (1172187917) |
0 |
EDX = [ESP] = [$18F2C0] = 0 ($0)
ESP = ESP + $4 = $18F2C4 + $4 = $18F2C8 |
FMULP |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = 0,272921267198399 ST1 = Empty |
$45DE2B0D (1172187917) |
0 |
ST(0) = ST(0) * ST(1) = 1172187917 * 2,3283064365387 * 10-10 =
0,272921267198399 |
FSTP TBYTE PTR Result |
$00000000 (0) |
$0018F2C8 |
- |
ST0 = Empty |
$45DE2B0D (1172187917) |
0,272921267198399 |
Result = ST(0) = 0,272921267198399 |
Вывод: 5 число = 0,272921267198399, RandSeed = 1172187917 |
Далее аналогичным образом рассчитываются следующие числа.
Примечание 1. Здесь дополнительно используется
значение регистра ESP – это указатель вершины стека. В регистре
ESP хранится адрес последней добавленной записи.
Примечание 2. Строки "ADD ESP, $4 " и
"POP EDX " можно заменить одной строкой "ADD ESP, $8 ".
Это означает, что команда ADD увеличит значение регистра
ESP сразу на 8, а в регистре EDX останется старое
значение.
|