Неверов Евгений Викторович
Меню сайта
Категории раздела
Программирование на языке Паскаль [27]
В данной категории представлены новые функции, созданные на языке Паскаль, которые могут пригодиться при написании своих программ
Программирование на Delphi [18]
В данной категории представлены полезные подпрограммы, которые могут пригодиться при написании своих программ, а также рассматриваются примеры готовых проектов, создаваемых в среде программирования Delphi
Программирование на HTML [0]
В данной категории рассматриваются примеры готовых проектов, создаваемых на языке HTML
Прочее [0]
Свободная тематика
Мини-чат
200
Наш опрос
Оцените мой сайт
Всего ответов: 41
Статистика

Рейтинг@Mail.ru
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Программирование на Delphi [ Добавить статью ]

Генератор псевдослучайных чисел (ГПСЧ). Часть 2

Начало...

Рассмотрим работу функции для вещественных (дробных) чисел.


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(r) на Random4(r).

Тексты в 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 останется старое значение.

Категория: Программирование на Delphi | Добавил: newerow1989 (06.03.2017 09:29 )
Просмотров: 123 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Все смайлы
Код *:
Поиск
Друзья сайта
  • Создать сайт
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Все проекты компании
  • Copyright MyCorp © 2018
    Автор этого сайта: Неверов Евгений Викторович

    Мои координаты
    Бесплатный конструктор сайтов - uCozЯндекс.Метрика