Blog. Just Blog

Генератор XorShift128 на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Генератор XorShift128 на Ассемблере
Генератор XorShift128 на Ассемблере

Генератор случайных чисел XorShift128 напоминает уже известное вам семейство генераторов xoshiro128. Из названия понятно, что тут используются только команда XOR и сдвиговые команды SHL/SHR, а период равняется 2128-1. В алгоритме отсутствуют операции деления и умножения, поэтому его можно использовать в тех микроконтроллерах, где таких ассемблерных операций нет в принципе. Также генератор XorShift является одними из самых быстрых генераторов случайных чисел.

Для работы генератора потребуется буфер в памяти размером 128 бит.
  1. ;---------------------------------------------
  2. ; Данные для генератора случайных чисел
  3.  
  4. s  rd 4
Начальная инициализация генератора ничем не регламентирована, поэтому я взял функцию инициализации и первоначального "засеивания" из генератора xoshiro128. Ну а что, там 128 бит и тут 128 бит, чего добру пропадать.
  1. ;---------------------------------------------
  2. ; Инициализация генератора случайных чисел
  3. ; stdcall xorshift_init,seed
  4. ;---------------------------------------------
  5. proc xorshift_init seed:DWORD
  6.         locals
  7.              s0 dd ?
  8.              s1 dd ?
  9.              s2 dd ?
  10.              s3 dd ?
  11.         endl
  12.  
  13.         pusha
  14.  
  15.         ; Начальное "засеивание" генератора
  16.         mov     edi,s
  17.         mov     eax,[seed]
  18.         rol     eax,1
  19.         xor     eax,0x1C580662
  20.         stosd
  21.         rol     eax,3
  22.         add     eax,0x0B6F099F
  23.         stosd
  24.         rol     eax,5
  25.         xor     eax,0xB523952E
  26.         stosd
  27.         rol     eax,7
  28.         sub     eax,0xCCF5A0EF
  29.         stosd
  30.  
  31.         ; Холостая прокрутка генератора для инициализации
  32.         lea     edi,[s0]
  33.         push    edi
  34.         xor     eax,eax
  35.         stosd
  36.         stosd
  37.         stosd
  38.         stosd
  39.  
  40.         xor     ebx,ebx
  41. .loc_for_1:
  42.         xor     ecx,ecx
  43. .loc_for_2:
  44.         mov     eax,[.lj+ebx*4]
  45.         and     eax,1
  46.         shl     eax,cl
  47.         jz      @f
  48.  
  49.         mov     esi,s
  50.         lodsd
  51.         xor     [s0],eax
  52.         lodsd
  53.         xor     [s1],eax
  54.         lodsd
  55.         xor     [s2],eax
  56.         lodsd
  57.         xor     [s3],eax
  58. @@:
  59.         stdcall xorshift
  60.  
  61.         inc     ecx
  62.         cmp     ecx,32
  63.         jb      .loc_for_2
  64.  
  65.         inc     ebx
  66.         cmp     ebx,4
  67.         jb      .loc_for_1
  68.  
  69.         pop     esi
  70.         mov     edi,s
  71.         movsd
  72.         movsd
  73.         movsd
  74.         movsd
  75.  
  76.         popa
  77.         ret
  78.  
  79. .lj:    dd 0xB523952E
  80.         dd 0x0B6F099F
  81.         dd 0xCCF5A0EF
  82.         dd 0x1C580662
  83. endp
Для своих проектов вы можете использовать менее навороченную функцию инициализации, например, исключив из нее цикл холостого прогона.
  1. ;---------------------------------------------
  2. ; Инициализация генератора случайных чисел
  3. ; stdcall xorshift_init,seed
  4. ;---------------------------------------------
  5. proc xorshift_init seed:DWORD
  6.         pusha
  7.  
  8.         ; Начальное "засеивание" генератора
  9.         mov     edi,s
  10.         mov     eax,[seed]
  11.         rol     eax,1
  12.         xor     eax,0x1C580662
  13.         stosd
  14.         rol     eax,3
  15.         add     eax,0x0B6F099F
  16.         stosd
  17.         rol     eax,5
  18.         xor     eax,0xB523952E
  19.         stosd
  20.         rol     eax,7
  21.         sub     eax,0xCCF5A0EF
  22.         stosd
  23.  
  24.         popa
  25.         ret
  26. endp
А вот сама функция получения случайного числа.
  1. ;---------------------------------------------
  2. ; Получить случайное число
  3. ; stdcall xorshift
  4. ; на выходе EAX - случайное число
  5. ;---------------------------------------------
  6. proc xorshift
  7.         pusha
  8.  
  9.         mov     eax,[s+0*4]
  10.         mov     ecx,eax
  11.         shl     eax,11
  12.         xor     ecx,eax
  13.  
  14.         mov     eax,[s+1*4]
  15.         mov     [s+0*4],eax
  16.         mov     eax,[s+2*4]
  17.         mov     [s+1*4],eax
  18.         mov     eax,[s+3*4]
  19.         mov     [s+2*4],eax
  20.  
  21.         mov     eax,ecx
  22.         shr     eax,8
  23.         xor     ecx,eax
  24.  
  25.         mov     eax,[s+3*4]
  26.         mov     ebx,eax
  27.         shr     eax,19
  28.         xor     ebx,eax
  29.         xor     ebx,ecx
  30.         mov     [s+3*4],ebx
  31.  
  32.         mov     [esp+28],ebx
  33.  
  34.         popa
  35.         ret
  36. endp
При минимальном объеме кода достигается крайне высокая скорость работы генератора, а по результатам он даже проходит статистические тесты diehard. То есть для решения прикладных задач, не связанных с криптографией, XorShift128 более чем достаточно.

В приложении пример программы с исходным текстом, которая генерирует псевдослучайные числа по алгоритму XorShift128.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

XorShift128.Demo.zip (3,208 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 991 | Комментариев: 0

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 2 (0.005 сек.) / Память: 4.5 Mb
Наверх