Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.11.14;
Скачать: [xml.tar.bz2];

Вниз

Циклический сдвиг вправо и влево   Найти похожие ветки 

 
DelphiDummy   (2002-10-31 22:31) [0]

Мастера! Подскажите, пожалуйста, есть ли в Delphi операция циклического сдвига вправо и влево? В Builder`е этим занимаются функции _lrotr и _lrotl. А есть ли что-либо подобное и в Delphi?

И еще: если такой функции все же нет, то не подскажет ли кто-нибудь, как с помощью стандартных функций Delphi написать функцию циклического сдвига?

Заранее всем ответившим большое спасибо!


 
Ученик   (2002-10-31 23:00) [1]

Поддерживается встроенный ассемблер
asm
...
end


 
Anatoly Podgoretsky   (2002-10-31 23:16) [2]

если без использования АСМ то иожно так (для 32 бит)
if N and 1 <> 0 then N shr 1 or $80000000 else N shr 1
if N and $80000000 <> 0 then N shl 1 or 1 else N shl 1


 
DelphiDummy   (2002-11-01 10:13) [3]

Дело в том, что я не знаю ассемблера вообще. То есть, приблизительно я представляю, как прикрутить ассемблерную вставку к своей программе, но то, что будет написано внутри asm ... end, я все равно объснить не смогу.

А насчет второго варианта я не совсем понял: во-первых, там где-нибудь должны стоять скобки или нет? Во-вторых, что это за цифра такая -- 80000000? Что она означает в данном случае?

Спасибо!


 
Alx2   (2002-11-01 10:18) [4]

>DelphiDummy (01.11.02 10:13)
asm
ror (или rol) variable <то, в чем сдвигаем>, 3 // - то на что сдвигаем
end;


 
Ученик   (2002-11-01 10:20) [5]

{ Project JEDI Code Library (JCL) }
//------------------------------------------------------------------------------

type
TBitRange = Byte;

function LRot(const Value: Byte; const Count: TBitRange): Byte; assembler;
asm
MOV CL, Count
ROL AL, CL
end;

//------------------------------------------------------------------------------

function LRot(const Value: Word; const Count: TBitRange): Word; assembler;
asm
MOV CL, Count
ROL AX, CL
end;

//------------------------------------------------------------------------------

function LRot(const Value: Integer; const Count: TBitRange): Integer; assembler;
asm
MOV CL, Count
ROL EAX, CL
end;

//------------------------------------------------------------------------------

function RRot(const Value: Byte; const Count: TBitRange): Byte; assembler;
asm
MOV CL, Count
MOV AL, Value
ROR AL, CL
MOV Result, AL
end;

//------------------------------------------------------------------------------

function RRot(const Value: Word; const Count: TBitRange): Word; assembler;
asm
MOV CL, Count
MOV AX, Value
ROR AX, CL
MOV Result, AX
end;

//------------------------------------------------------------------------------

function RRot(const Value: Integer; const Count: TBitRange): Integer; assembler;
asm
MOV CL, Count
MOV EAX, Value
ROR EAX, CL
MOV Result, EAX
end;


 
Dr_Mike   (2002-11-01 10:28) [6]

А почему все функции завершаются именно так "MOV Result, AL(AX,EAX)" ???


 
han_malign   (2002-11-01 10:41) [7]

function _shl(Operand : word; Count: byte): WORD;
asm
push CX //возможно не нужно - непомню
mov CL,Count
shl AX,DX
pop CX //возможно не нужно - непомню
end;

для други типов
function _shl(Operand : Dword; Count: byte): DWORD;
asm
push CX //возможно не нужно - непомню
mov CL,Count
shl EAX,CL
pop CX //возможно не нужно - непомню
end;
function _shl(Operand : byte; Count: byte): byte;
asm
push CX //возможно не нужно - непомню
mov CL,Count
shl AL,CL
pop CX //возможно не нужно - непомню
end;

аналогично
RCx - циклический через флаг переноса
ROx - циклический через флаг переполнения
SAx - арифметический(не трогается знаковый бит)
SHx - сдвиг
SHxD- сдвигает превый операнд с присоединенным вторым
function _SHxD(Operand: int64;Count: byte):int64;
asm
push CX //возможно не нужно - непомню
mov CL,Count
SHxD EAX,EDX,CL
pop CX //возможно не нужно - непомню
end;

где x - L или R
короче
http://webster.cs.ucr.edu/Page_TechDocs/Doc386
или найди TechHelp(еще досовский справочник)

З.Ы. в Паскале целочисленные аргументы впихиваются в аккумуляторы (пару EAX:EDX)если помещаются, аналогично Result - тоже соответствует этой регистровой паре, поэтому приведенные примеры полностью функциональны.


 
Ученик   (2002-11-01 10:46) [8]

>Dr_Mike © (01.11.02 10:28)
Хороший вопрос, видимо, разные люди писали :-)


 
han_malign   (2002-11-01 10:48) [9]

Кстати MOV Result, AL(AX,EAX) совсем не нужен потому что фактичечески Result это тоже AL(AX,EAX,EAX:EDX)


 
han_malign   (2002-11-01 11:59) [10]

Извиняюсь int64 в функцию передается через стек поэтому
function _SHRD(const Value: int64; const Count: byte): int64; assembler;
asm
MOV CL,AL//Count
MOV EAX,DWORD PTR([Value])
MOV EDX,DWORD PTR([Value+4])
SHRD EAX,EDX,CL
SHR EDX,CL
end;
function _SHLD(const Value: int64; const Count: byte): int64; assembler;
asm
MOV CL,AL//Count
MOV EAX,DWORD PTR([Value])
MOV EDX,DWORD PTR([Value+4])
SHLD EDX,EAX,CL
SHL EAX,CL
end;


 
Dr_Mike   (2002-11-02 00:25) [11]

А точно через стек ???


 
apay   (2002-11-02 01:03) [12]

Я вообще не пойму, зачем нужны:
MOV Result, EAX
MOV EAX, <Param1>

при передаче пар-ров типа Byte, Word, Integer, Pointer ...
если не указано stdcall или что то подобное,
первый пар-р в EAX(AX или AL) , второй в EDX, третий в ECX, остальные ч/з стек.
Result берется из EAX (AX, AL), иногда EDX:EAX


 
Anatoly Podgoretsky   (2002-11-02 09:07) [13]

Dr_Mike © (01.11.02 10:28)
Хороший вопрос, ответ от незнания автором данной библиотеки Дельфи, к тому же непоследовательносять, в одних есть, а в других нет.

У него есть и вторая незначительная ошибка - ключевое слово Assembler лишнее. И так еще по мелочам.


 
DelphiDummy   (2002-11-02 11:10) [14]

В данный момент у меня в программе написано просто:

asm
ror Mask1, 4
end;

Это синтаксически правильно? Или все-таки нужно писать все, что мне указал здесь Ученик? И кстати, в том варианте, который написал Ученик, я так понял, есть ошибки? Не мог бы кто-нибудь точно сказать, что за ошибки?

Есть еще один вопрос глупый, но все-таки хотелось бы спросить: мне что, все сразу функции писать (из тех, которые здесь написал ученик) или просто нужно выбрать одну из них для своего типа переменных?

Спасибо!


 
DelphiDummy   (2002-11-02 11:29) [15]

Уважаемый han_malign! Я ничего не понял из того, что Вы написали. По ссылке, которую Вы мне дали, я не нашел ничего, кроме кучи html-файлов. Загрузил один из них и получил длинный список, в котором я ничего не понял. Вот одна из строчек в этом списке:

D0 /0 ROL r/m8,1 3/7 Rotate 8 bits r/m byte left once

Что такое D0? Что такое /0? Что такое r? Что такое m8?.. В общем, что такое это все?

А если я в программе написал просто rol Mask1, 4 или ror Mask1, 4 -- это разве не циклический сдвиг вправо и влево?


 
down   (2002-11-02 12:06) [16]

пиши просто X := Y shr {или shl} Z


 
DelphiDummy   (2002-11-02 12:09) [17]

Нда... Ну, спасибо, down, за бесполезный совет. Повторюсь: мне нужен не побитовый сдвиг, а именно циклический. Разница, надеюсь, понятна?


 
DelphiDummy   (2002-11-02 12:13) [18]

Кстати, господа! На все ваши варианты компилятор Delphi 5.5 ругается, что inline assembler error или что-то в этом роде. Короче говоря, ошибка внутреннего ассемблера. В help"е написано, что встроенный компилятор ассемблера увидел ошибку в ассемблерной вставке в моей программе. И ругань эта идет и на вариант от пользователя Ученик, и на вариант от пользователя han_malign.

Вопрос: неужели никто не может подсказать реально работающую функцию циклического сдвига? Чтобы было еще понятнее и дабы сократить размеры ответов, напишу, что есть переменная-маска Mask1 типа Integer, которую надо сместить вправо сначала на четыре бита, потом еще на четыре, а потом вернуть влево на 11 бит. Исходя из этого никто не может мне писать ассемблерную вставку в программу, реально позволяющую осуществить то, что я написал?

Спасибо!


 
down   (2002-11-02 12:23) [19]

а, извини, невимательно прочитал
может быть, это поможет (из idglobal.pas, не знаю, есть ли в D5)function ROL(val: LongWord; shift: Byte): LongWord; assembler;
asm
mov eax, val;
mov cl, shift;
rol eax, cl;
end;

function ROR(val: LongWord; shift: Byte): LongWord; assembler;
asm
mov eax, val;
mov cl, shift;
ror eax, cl;
end;


 
Anatoly Podgoretsky   (2002-11-02 12:57) [20]

down (02.11.02 12:23)
Это пишется так:


function ROL(val: LongWord; shift: Byte): LongWord;
asm
mov cl, dl;
rol eax, cl;
end;

function ROR(val: LongWord; shift: Byte): LongWord;
asm
mov cl, dl;
ror eax, cl;
end;


Для Д3 LongWord заменяется на Longint


 
down   (2002-11-02 13:05) [21]

Anatoly Podgoretsky © (02.11.02 12:57)
ok, передам разработчикам Indy


 
Anatoly Podgoretsky   (2002-11-02 13:10) [22]

Не надо, это их право так писать, сделай им снисхождение, не все же грамотные, тем более что страшного ничего нет, рабочий код в обоих случаях


 
DelphiDummy   (2002-11-02 13:11) [23]

Anatoly Podgoretsky (02.11.02 12:57)

А для типа Integer пишется так же, как и для LongWord? Сейчас попробую вставить указанное Вами в мою программу. О результатах сообщу дополнительно.


 
Anatoly Podgoretsky   (2002-11-02 13:15) [24]

Не надо сообщать, это работает много лет, начиная с Д2, для Д1 немного по другому
С интегер сложнее, размер у него задается компилятором и неоднократно менялся, да и смысла делать циклический сдвиг для знаковых как то непонятен


 
DelphiDummy   (2002-11-02 13:25) [25]

Anatoly Podgoretsky (02.11.02 13:15)

OK! Рассказываю все с самого начала. Есть задача: реализовать алгоритм блочного шифрования ГОСТ-28147-89 в Delphi. Кто знаком с этим алгоритмом, тот знает, что там используется функция циклического сдвига.

Более того, у меня уже есть абсолютно точно работающая программа, написанная на Builder`е. Задача облегчается: теперь надо просто переписать эту программу на Delphi. Я переписал, запустил -- не работает. Все проверки всех полей работают, но как только нажимаешь на кнопку шифрования, выдается ошибка Access violation at address 0044AF17 in module "lab2.exe". Read of address 005EC2F8. Так как я понятия не имею, что точно не работает, то подумал, что дело в функции циклического сдвига.

Я вставил код, представленный Вами, Анатолий, все опять же запускается, но ошибка не исчезает. В связи с этим вопрос: не могли бы Вы мне помочь разобраться с этим делом? Я мог бы прислать по почте уже работающую программу на Builder`е и прислать свой вариант на Delphi. Быть может, для мастера не составит труда найти ошибку. Может быть, я вообще не там ищу, и ошибка-то вот она, но я ее не вижу. Если можно так сделать, напишите, пожалуйста, здесь об этом. Заранее спасибо!

to All: Народ! Кто-нибудь еще может мне помочь с переписыванием программы на Builder`е под Delphi? Кто знаком с алгоритмами шифрования и, в частности, с алгоритмом ГОСТ-28147-89?


 
down   (2002-11-02 13:27) [26]

Дебуггер не помогает?


 
DelphiDummy   (2002-11-02 13:34) [27]

down (02.11.02 13:27)

> Дебуггер не помогает?

Нет, не помогает. Может быть, ты можешь помочь? Если есть время, конечно...


 
Anatoly Podgoretsky   (2002-11-02 13:38) [28]

Так у тебя ощибка не зжесь, а в другом месте, согласно сообщение у тебя гдето обращение не к иничиализированному или чужому адресу, самое вероятное где то неинициализированный или испорченный указатель. Ошибки такого рода иногда очень трудно найти, правильнее не делать ошибок.


 
DelphiDummy   (2002-11-02 13:43) [29]

Anatoly Podgoretsky (02.11.02 13:38)

Ну, так Вы мне не поможете найти эту ошибку? Программа на Delphi не очень большая... Просто я уже запарился ее искать. Не знаю, где там и что у меня не инициализировано, потому что я переписывал программу в точности с работающей программы, написанной на Builder`е. Почему на Builder`е она работает, а на Delphi нет, я не знаю.


 
DelphiDummy   (2002-11-02 13:45) [30]

Кстати, на сайте готовых решений, ссылка на который есть на этом сайте, я нашел такую функцию в одной из программ:

function ROTATE_LEFT(x, n: UINT4): UINT4;
begin
Result := (((x) shl (n)) or ((x) shr (32-(n))));
end;


Разве это не решение? Это ли не функция циклического сдвига? Или эта функция и те, которые были здесь приведены на asm -- это две разные вещи?


 
down   (2002-11-02 13:48) [31]

Range checking включено?


 
DelphiDummy   (2002-11-02 13:56) [32]

down (02.11.02 13:48)

> Range checking включено?

Извините, конечно, но что такое range checking?


 
down   (2002-11-02 14:03) [33]

Range checking - проверка на выход за границы массива. Выход за границы массива иногда (в лучшем случае) вызывает AV => может помочь


 
DelphiDummy   (2002-11-02 14:15) [34]

down (02.11.02 14:03)

> Range checking - проверка на выход за границы массива. Выход за
> границы массива иногда (в лучшем случае) вызывает AV => может
> помочь

Честно говоря, я вообще не понимаю, о чем Вы говорите. К моему большому сожалению, я не умею пользоваться debugger`ом. :(

Как же мне все-таки понять, что за ошибка у меня в программе? :(


 
down   (2002-11-02 14:29) [35]


> Честно говоря, я вообще не понимаю, о чем Вы говорите. К
> моему большому сожалению, я не умею пользоваться debugger`ом.
> :(

Тааак... с этого и надо было начинать. Действительно, как дебуггер может помочь, если пользоваться им не не умеешь.
Самое время научиться.
1.Поставь точку останова в начале процедуры, вызываемой при нажатии кнопки "зашифровать" (правая кнопка манипулятора, add breakpoint)
2.Запускаем программу, давим "зашифровать", нажимаем F7, пока не появится ошибка.
3.Смотрим, что ее вызвало, исправляем.
А вообще, см. книжку "Delphi for dummies" :)


 
DelphiDummy   (2002-11-02 14:48) [36]

Спасибо, конечно, но Вы уверены, что последовательность действий именно такая?

1. BreakPoint я поставил. Но! Процедура, Encrypt_ButtonClick у меня состоит всего из трех строчек: задаются два параметра, потом управление передается другой процедуре. А именно:

procedure TMain_Form.encrypt_buttonClick (Sender: TObject);

begin
param1 := 3;
param2 := 1;
Code (True)
end;


2. Запускаю программу клавишей F9, надимаю на кнопку `Зашифровать`, программа вываливается длинным сообщением и окошком с кнопкой OK. Нажимаю на кнопку OK, нажимаю F7, выделяется строка с вышеприведенной функцией, и все! И что мне это дало?

3. Я, конечно, был бы рад посмотреть, что вызвало ошибку, но только как это реально сделать-то?

P.S. И насчет книжки... а где ее взять-то? :)


 
down   (2002-11-02 15:02) [37]

Что за сообщение-то? И у меня написано - нажимать Ф7, пока не появится ошибка, а ты один раз нажал.
Про книжку я пошутил, не знаю, есть ли такая, просто есть такая серия - "Word for dummies", "Excel for dummies" (на русский переводятся как "... для идиотов"), и псевдоним у тебя подходящий.


 
DelphiDummy   (2002-11-02 15:28) [38]

За идиота спасибо, конечно. :( Dummy -- это вообще-то не идиот, а чайник. Но это я так, на всякий случай. Сообщение у меня следующее (дословно):

Project lab2.exe raised exception class EAccessViolation with message "Access violation at address 0044AF27 in module "lab2.exe". Read of address 003EFFFC". Process stopped. Use Step or Run to continue.

Это написано в окошке с кнопкой OK. Нажимаю OK. Нажимаю F7, курсор перемещается к началу процедуры, где я ставил BreakPoint, и все. При повторном нажатии F7 ничего не происходит.

И что дальше?


 
DelphiDummy   (2002-11-02 15:34) [39]

А может, я вообще breakpoint неправильно ставлю? Я делаю это так: захожу в меню Run, выбираю там строчку Add Breakpoint, и в ней выбираю Source Breakpoint. Так или нет? Потому что при нажатии правой кнопки мышки у меня никакой add breakpoint нет. :(

P.S. Я скоро с ума сойду с этой программой. И самое обидное, что вот она, лежит рядом на Builder`е, прекрасно работает, а вот на Delphi не работает, хотя написана точь-в-точь так же. :( Эх...


 
down   (2002-11-02 16:00) [40]


> За идиота спасибо, конечно. :(

Это книжки у нас такие продаются, я тебя идиотом не считаю, ok?
Кстати, может быть, не "... для идиотов", а "... для чайников"... Но "... для идиотов" тоже что-то вроде было...

Про то, как установить точку останова, я сказал не совсем правильно, извини. Нужно нажать правой кнопкой на требуемой строчке, потом в меню выбрать Debug -> Toggle breakpoint (или F5).

Точку останова нужно поставить в строке, выполняемой до того, как проявляется ошибка. Если у тебя ошибка проявляется при нажатии кнопки шифрования, то поставь ее на месте (*), там должна появиться красная точка.

begin
(*) param1 := 3;
param2 := 1;
Code (True)
end

Если при нажатии на кнопку выполняется эта процедура, то программа остановится на строчке (*), никаких окошек до этого показываться не должно. Далее нажимаешь Ф7, пока не дойдешь до ошибки.



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2002.11.14;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.008 c
14-46070
Николай Быков
2002-10-24 15:35
2002.11.14
http://freeprogrammer.narod.ru


1-45983
aQQQa
2002-11-03 21:52
2002.11.14
Помогите! Очень срочно!


1-45868
Sergy
2002-11-05 14:46
2002.11.14
Нужна звонилка до провайдера


1-45801
KME
2002-11-04 22:26
2002.11.14
Шрифты


3-45691
alexts
2002-10-25 14:21
2002.11.14
Проблема MS SQL 2000 и OLE





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский