![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Дельфийские аналоги функций _lrotr и _lrotr [D7, WinXP]
andreil © (2008-05-06 23:53:00)Собственно никтог не видел? А то без них никак OBJ-файл не подключить, ругается на отсутствие этих функций. Их описание я на шел, но вот сами функции - нет :(
Поможет кто?
Renegat (2008-05-08 00:34:00) [21]> Гм, а на 386 хотя бы Windows 95 запустится?
А то как же? Правда тормозов будет... ууу %)
Ибо триставосьмидесятники они уже 32-разрядные, в отличие от двести-, сто-, и просто восьмидесятников.
В принципе, под двойки пожет пойти Win 3.11 - а посему совместимость тоже нужна :D
Тыщ (2008-05-08 00:13:00) [22]Renegat (07.05.08 20:22) [19]
> совместимость со старым хламом типа .286 и .386
Гм, а на 386 хотя бы Windows 95 запустится? Если нет, то обеспечивать такую совместимость в прикладных прогах смысла никакого.
Renegat (2008-05-07 20:22:00) [23]> static ulong FlipDword(ulong d)
Хоспади!!! о_0 Какие усилия для банальной перестановки байт!!! BSWAP и всё! Или нужна-таки совместимость с .386 и ниже? Если так, то
function FlipDword(n:DWORD):DWORD;
asm
XCHG AL, AH;
ROR EAX, 16;
XCHG AL, AH;
end;
если же совместимость со старым хламом типа .286 и .386 не требуется, то можно обойтись этим:
function FlipDword(n:DWORD):DWORD;
asm
BSWAP EAX;
end;
andreil (2008-05-07 20:18:00) [24]Да, забыл написать, часто в качастве параметра передается 0 (если ключик дешифровки не указан).
andreil (2008-05-07 20:12:00) [25]
> Опана... Это как это?! У себя проверил - всё работает отлично.
> .. Вы точно больше 31 в Num не передаёте?Вывод один - показывайте
> код
Код на С++ не мой, а на дельфи перевести не сумел - там все замешано на указателях. Вот кусок кода, вызывающий эти функции:
static ulong FlipDword(ulong d)
{
return (_lrotr(d, 8)&0xFF00FF00) | (_lrotl(d, 8)&0x00FF00FF);
}
static void FlipDwordString(ulong *dst, ulong *src, int blen)
{
int i;
for (i = 0; i < (blen+3)>>2; i++)
dst[i] = FlipDword(src[i]);
}
Renegat, DevilDevil ©- нифига не пашет, вылет на 9 вызове.
А нашел я вариант, указанный во втором сообщении в файлах "Source\Rtl\Source\math\lrotl.asm" и "Source\Rtl\Source\math\lrotr.asm", входящих в комплект поставки CBuilder6.
DevilDevil (2008-05-07 18:47:00) [26]> Renegat (07.05.08 18:35) [14]
дабы не париться лишний раз с параметрами, рекомендую их не писать; в приведённом мной листинге, как Вы успели заметить, их нет. "Функции" тоже лучше заменять на процедуры.
Renegat (2008-05-07 18:41:00) [27]Да и вообще, почему procedure? И плюс ещё список параметров не определён.
Если уж пошла такая пьянка, то вот:
function lrotr(N:ULONG; Num:DWORD):ULONG; stdcall;
asm
MOV EAX, DWORD PTR [ESP+4]
MOV ECX, DWORD PTR [ESP+8]
ROR EAX, CL
end;
function lrotl(N:ULONG; Num:DWORD):ULONG; stdcall;
asm
MOV EAX, DWORD PTR [ESP+4]
MOV ECX, DWORD PTR [ESP+8]
ROL EAX, CL
end;
Renegat (2008-05-07 18:35:00) [28]> [13] DevilDevil © (07.05.08 18:26)
Тогда надо добавить директиву, ибо без неё Вам Делфи парамы в стек не запишет:
procedure _lrot; stdcall;
...
procedure _lrotr; stdcall;
DevilDevil (2008-05-07 18:26:00) [29]имхо:
[code]
procedure _lrot;
asm
mov eax, [esp+4] ; get value
mov ecx, [esp+8] ; get rotate count
rol eax,cl ; rotate the value
end;
procedure _lrotr
asm
mov eax, [esp+4] ; get value
mov ecx, [esp+8] ; get rotate count
ror eax,cl ; rotate the value
end; [/code]
линкеру нужен только адрес вызова и всё, "параметры" он сам "подставит".
P.S. а где ты нашёл эти и аналогичные функции ? Мне, например, нужны ldexp всякие.
Renegat (2008-05-07 17:35:00) [30]> Хм. Это в Билдере так называется? Для Дельфи первое - register.
> А safecall в Дельфи (если верить справке) не передаёт параметры
> через регистры.
Чорт. Нет, определённо надо было уже спать ложиться %) Имелся в виду __fastcall
Да и с количеством команд напутал. Выполнаются-то не две а три...
Простите дурака :)
> Не то :( При работе 8 раз вызывается нормально, а на 9-ом - вылет.
Опана... Это как это?! У себя проверил - всё работает отлично... Вы точно больше 31 в Num не передаёте?
Вывод один - показывайте код
han_malign (2008-05-07 12:22:00) [31]offtop
> А safecall в Дельфи (если верить справке) не передаёт параметры
> через регистры.
- safecall это stdcall, плюс генерация исключения если после возврата EAX <> 0
это обертка:
exportfunction fff(...): HRESULT; stdcall;==>
importprocedure fff(...): safecall;
Anatoly Podgoretsky (2008-05-07 12:01:00) [32]Второй от третьего отличается только соглашением о вызове.
Оно тебе надо?
Если надо, то cdecl/stdcall
palva (2008-05-07 10:39:00) [33]Лучше не заниматься самодельщиной. Нужно просто вытащить объектник из соответствующей библиотеки cw32.lib (или cw32mt.lib и т. д.) утилитой tlib например так:
tlib.exe cw32.lib*rotr
включить его в юнит. Правильный header к этой функции составить на основе билдерной документации или пройтись по нему отладчиком и понять какой он должен быть.
В таких функциях может быть много нюансов, связанных с многопоточностью или с обращением к другим функциям библиотеки или к библиотеке cc3250.dll
andreil (2008-05-07 10:25:00) [34]
> Сопстна вот.
Не то :( При работе 8 раз вызывается нормально, а на 9-ом - вылет.
> PS Лучше не делать Num связок по две операции, как в примере
> из поста #1, а обойтись всего двумя, как в #2.
Во втором посте вооющето сделано на чистом АСМе, да и взято с С++ Буилдера, поэтому 100% правильно. Но вот как перевести это на Дельфи?
ЗЫ: В АСМе я не силен :(
Германн (2008-05-07 01:13:00) [35]
> Renegat (07.05.08 00:56) [6]
>
> > Не знаю точно, что должны делать эти функции, но на вскидку+телепатор
> вроде как похоже на "то".
> Эти функции должны сдвигать число на Num двоичных разрядов
> влево/вправо с записью цепочки "выдвигаемых" битов в другой
> конец числа.
>
Я так и подумал.
> Ага. Первое - __safecall(первые три парама - EAX, EDX и
> ECX, далее - в стэк)
Хм. Это в Билдере так называется? Для Дельфи первое - register. А safecall в Дельфи (если верить справке) не передаёт параметры через регистры.
> PS Лучше не делать Num связок по две операции, как в примере
> из поста #1, а обойтись всего двумя, как в #2.
>
Это очевидно. Сомнений нет.
Renegat (2008-05-07 00:56:00) [36]> Не знаю точно, что должны делать эти функции, но на вскидку+телепатор вроде как похоже на "то".
Эти функции должны сдвигать число на Num двоичных разрядов влево/вправо с записью цепочки "выдвигаемых" битов в другой конец числа.
> Второе то же самое, только там соглашение о вызовах другое.
Ага. Первое - __safecall(первые три парама - EAX, EDX и ECX, далее - в стэк), второе - __stdcall (только стэк)
PS Лучше не делать Num связок по две операции, как в примере из поста #1, а обойтись всего двумя, как в #2.
Anatoly Podgoretsky (2008-05-07 00:54:00) [37]Циклический сдвиг на Эн бит.
Перевод сделан правильно.
Германн (2008-05-07 00:42:00) [38]
> andreil © (06.05.08 23:56) [1]
>
> Вроде как нашел на АСМ-ие, но может не то?
>
Не знаю точно, что должны делать эти функции, но на вскидку+телепатор вроде как похоже на "то".
Второе то же самое, только там соглашение о вызовах другое.
Renegat (2008-05-07 00:38:00) [39]function lrotr(N:ULONG; Num:DWORD):ULONG;
asm
MOV ECX, EDX
ROR EAX, CL
end;
function lrotl(N:ULONG; Num:DWORD):ULONG;
asm
MOV ECX, EDX
ROL EAX, CL
end;
Сопстна вот. Хотя номинально тип 2-го парама позволяет записать в него любую бяку вплоть до 0FFFFFFFFh, больше 1Fh (т.е. 31) скармливать этим функциям не рекомендуется.
andreil (2008-05-06 23:58:00) [40]ООО нашел таки, но только на чистом АСМе с СиБуилдера.
Поможете перевести на дельфийский?
Func@ _lrotl, _EXPFUNC, _RTLENTRY, <long val>, <int rcount>
mov eax, [esp+4] ; get value
mov ecx, [esp+8] ; get rotate count
rol eax,cl ; rotate the value
Return@
EndFunc@ _lrotl
Func@ _lrotr, _EXPFUNC, _RTLENTRY, <long val>, <int rcount>
mov eax, [esp+4] ; get value
mov ecx, [esp+8] ; get rotate count
ror eax,cl ; rotate the value
Return@
EndFunc@ _lrotr