Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.04.2010, 19:35   #1
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
Восклицание Random на ассемблере.

Добрый вечер!

Подскажите, пожалуйста, где можно найти ссылку на пример кода процедуры Random на ассемблере. Очень нужно.

Здесь на форуме есть такой код:

Код:
.data
nrandom_seed	dd 12345678

.code
nseed 	proc uses ebx edi esi, \
	TheSeed:DWORD
	mov	eax, TheSeed
	mov	nrandom_seed, eax
	ret
nseed 	endp

nrandom	PROC uses ebx edi esi, \
	base:DWORD
	
	mov	eax, nrandom_seed
	xor	edx, edx
	mov	ecx, 127773
	div	ecx
	mov	ecx, eax
	mov	eax, 16807
	mul	edx
	mov	edx, ecx
	mov	ecx, eax
	mov	eax, 2836
	mul	edx
	sub	ecx, eax
	xor	edx, edx
	mov	eax, ecx
	mov	nrandom_seed, ecx
	div	base
	mov	eax, edx
	ret
nrandom ENDP
но как его в delphi применить? Как правильно изменить запись этого кода, например, применительно к Delphi.

или как в делфи можно использовать следующий код:

Код:
;---------------------------------------------
; Park Miller random number algorithm
; Получить случайное число 0 ... 99999
; stdcall WRandom
; на выходе EAX - случайное число 
;---------------------------------------------
proc    WRandom
        push    edx ecx
        mov     eax,[random_seed]
        xor     edx,edx
        mov     ecx,127773
        div     ecx
        mov     ecx,eax
        mov     eax,16807
        mul     edx
        mov     edx,ecx
        mov     ecx,eax
        mov     eax,2836
        mul     edx
        sub     ecx,eax
        xor     edx,edx
        mov     eax,ecx
        mov     [random_seed],ecx
        mov     ecx,100000
        div     ecx
        mov     eax,edx
        pop     ecx edx
        ret
endp
 
;---------------------------------------------
; Получить случайное число в нужном интервале
; Требуется процедура WRandom
; stdcall WIRandom,min,max
; на выходе EAX - случайное число   
;---------------------------------------------
proc    WIRandom rmin:dword,rmax:dword
        push    edx ecx
        mov     ecx,[rmax]
        sub     ecx,[rmin]
        inc     ecx
        stdcall WRandom
        xor     edx,edx
        div     ecx
        mov     eax,edx
        add     eax,[rmin]
        pop     ecx edx
        ret
endp
 
;---------------------------------------------
; Инициализация генератора случайных чисел
; stdcall WRandomInit 
;---------------------------------------------
proc    WRandomInit
        push    eax edx
        rdtsc
        xor     eax,edx
        mov     [random_seed],eax
        pop     edx eax
        ret
endp
Вот так, например, не работает:

Код:
procedure WIRandom(rmin:dword;rmax: dword);
asm
        push    edx ecx // в этой строке пишет ошибка
        mov     ecx,[rmax]
        sub     ecx,[rmin]
        inc     ecx
        stdcall WRandom
        xor     edx,edx
        div     ecx
        mov     eax,edx
        add     eax,[rmin]
        pop     ecx edx
        ret
end;
Спасибо.

Последний раз редактировалось SkAndrew; 17.04.2010 в 19:42.
SkAndrew вне форума Ответить с цитированием
Старый 17.04.2010, 19:42   #2
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

А чем родная Random в связке с Randomize не устроила?
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 17.04.2010, 20:02   #3
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию

медленно работает. но не только в этом дело. в любом случае нужна информация о генераторе случайных чисел на ассемблере. Может кто подскажет ссылку или поможет адаптировать приведенные коды к делфи. Дискуссию о скорости мне не бы хотелось начинать. вопрос конкретный. Спасибо.
SkAndrew вне форума Ответить с цитированием
Старый 17.04.2010, 20:11   #4
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Код:
 push    edx ecx // в этой строке пишет ошибка
Потому что там не правильно.
http://www.codenet.ru/progr/asm/newbee/lesson3.php

Для первого кода:
nseed - устанавливает точку отсчета для генератора
nrandom - сам генератор

Как я понял (хотя могу и ошибаться) алгоритм основан на махинациях с остатком от деления (mod в терминологии Дельфи), то есть классический генератор псевдослучайных чисел - большой цикл повторяющихся чисел (просто последовательность повторяется через большое количество шагов, ну скажем через несколько миллионов запросов). раз требуется большая скорость, значит подразумевается частый вызов, и значит есть вероятность получить повторно ту же самую последовательность.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 17.04.2010, 20:29   #5
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию

Спасибо,

1. ссылка не открывается.

2. я не знаю ассемблера, поэтому и попросил помочь либо с готовым примеров в делфи, либо поправить приведенный.

3. буду весьма благодарен за конкретный ответ на поставленный вопрос.

Спасибо.
SkAndrew вне форума Ответить с цитированием
Старый 17.04.2010, 20:57   #6
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

1. Ссылка открывается . Даже если Вы не можете открыть сразу, можно попасть на ресурс, а оттуда на конкретный урок, было бы желание.
2. Во-первых, ассемблер не относится к Дельфи. Во-вторых, что мешает Вам найти самостоятельно в гугле описание команды push? Не так страшен черт как его малюют .
В общем, либо push edx, либо push ecx, но ни как не вместе. Почему ошибка я не знаю, но часто встречаю глупые ошибки в разного рода примерах (похоже закладываются специально).
3. Я ответил конкретно. Дело вот в чем, в моем ответе всегда достаточно информации, чтобы Вы подумав, смогли решить задачу. Иначе, через неделю Вы придете с подобным вопросом снова. Я хочу не решить поставленную Вами задачу, а научить Вас ее решать.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 17.04.2010, 21:39   #7
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,830
По умолчанию

Между прочим делфийский рандом тоже на асме...

2 Utkin
"В общем, либо push edx, либо push ecx, но ни как не вместе."
Не надо так категорично.... Есть асм и с подобным синтаксисом.
p51x вне форума Ответить с цитированием
Старый 17.04.2010, 21:40   #8
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию

Спасибо, но я не просил меня учить ассемблеру. я попросил помощи подсказать как можно адаптировать приведенный код к делфи если кто-то знает уже ассемблер или подсказать ссылку на готовый пример подобного кода. Спасибо еще раз всем кто может помочь.
SkAndrew вне форума Ответить с цитированием
Старый 19.04.2010, 09:47   #9
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Есть асм и с подобным синтаксисом.
В Дельфи? Речь ведь идет об определенном диалекте...
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 19.04.2010, 09:56   #10
Crusher
Пользователь
 
Регистрация: 13.12.2008
Сообщений: 27
По умолчанию

Код:
push edx ecx
pop ecx edx
Это на fasm. В делфи будет:
Код:
push edx 
push ecx
pop ecx 
pop edx
Чтобы в делфи адаптировать создавай процедуру:
Код:
function random(a,b:integer): integer; stdcall
asm
.... //тут тело процедуры на асме.
end;
Crusher вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
random в С++ Swool Общие вопросы C/C++ 21 18.02.2012 21:55
Random Febreze Общие вопросы Delphi 2 28.04.2008 14:17
Random Constellation БД в Delphi 2 10.01.2008 21:37