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

Вниз

Как осуществить сдвиг с переносом для 64 битного значения?   Найти похожие ветки 

 
Still Swamp   (2006-09-17 19:21) [0]

Как осуществить сдвиг с переносом для 64 битного значения?


 
begin...end ©   (2006-09-17 20:25) [1]

Не совсем понял, о каком переносе идёт речь. Если имеется в виду обычный линейный сдвиг 64-битного значения, размещённого в двух 32-разрядных регистрах, можно использовать команды сдвига двойной точности (SHLD, SHRD) -- они сдвигают операнд в нужном направлении, заполняя освободившиеся биты битами второго операнда.

Для примера можно рассмотреть, например, линейный сдвиг влево числа $123456789ABCDEF на 10 разрядов:

00000001001000110100010101100111  10001001101010111100110111101111  <-- исходное число (01234567 89ABCDEF)

10001101000101011001111000100110  10101111001101111011110000000000  <-- результат      (8D159E26 AF37BC00)

(регистры разделены пробелами). Очевидно, что для выполнения такого сдвига нужно сдвинуть содержимое старшего регистра на 10, заполняя его освобождающиеся младшие биты старшими битами младшего регистра (именно это и сделает команда SHLD), а содержимое младшего регистра просто сдвинуть на 10 разрядов влево, используя обычную SHL (старшие 10 битов регистра теперь можно спокойно потерять). Т.е. код будет такой:

MOV  EAX, $01234567  // старшая часть
MOV  ECX, $89ABCDEF  // младщая часть
SHLD EAX, ECX, 10    // линейный сдвиг двойной точности
SHL  ECX, 10         // обычный линейный сдвиг


Это если решать задачу в рамках ассемблерных вставок. А если речь об обычном дельфишном коде, то, само собой, нужно использовать Int64 (сдвиг для которого реализован, кстати, по описанному принципу) и не мучаться.


 
Still Swamp   (2006-09-17 22:13) [2]

С асмомо ответ исчерпывающий. А по поводу дельфи... есть там shl и shr. Но это сдвиг без переноса.


 
begin...end ©   (2006-09-17 22:49) [3]

> Still Swamp   (17.09.06 22:13) [2]

Вот код на языке Delphi, аналогичный ассемблерному коду из [1]:

var
 I: Int64;
begin
 I := $123456789ABCDEF;
 I := I shl 10;
 ShowMessageFmt("%x", [I])  <-- "8D159E26AF37BC00"
end.


Получается тот же самый результат, т.е. перенос сдвигаемых битов из младшего двойного слова переменной I в её старшее двойное слово происходит корректно, и delphi-оператор shl нормально работает с Int64-переменными.


 
Still Swamp   (2006-09-17 23:00) [4]

хм... может я сильно туплю, но еще раз. shl сдвигает без переноса сдвигаемых бит. я проверил этот факт.


 
oxffff ©   (2006-09-17 23:06) [5]

Что ты имеешь ввиду под переносом.

Сдвиг через флаг переноса CF


 
oxffff ©   (2006-09-17 23:08) [6]

Если использовать SHLD, SHRD , то в CF последний бит, участвовавший в сдвиге.


 
Still Swamp   (2006-09-17 23:08) [7]

Действие CF на оператор SHL в Delphi распространяется?


 
oxffff ©   (2006-09-17 23:13) [8]

Ты хочешь чтобы из CF на освободившееся место ?


 
oxffff ©   (2006-09-17 23:25) [9]

Тебе тогда надо использовать инструкции RCL или RCR


 
Pavia ©   (2006-09-18 00:05) [10]

Взять 128 битное число сделать сдвиг SHL потом сделать OR от нижней и верхней части.


 
Anatoly Podgoretsky ©   (2006-09-18 00:25) [11]

Что касается переноса придется делать на ассемблере, Дельфи не оперирует разрядом переноса.


 
Германн ©   (2006-09-18 00:39) [12]


> Anatoly Podgoretsky ©   (18.09.06 00:25) [11]
>
> Что касается переноса придется делать на ассемблере, Дельфи
> не оперирует разрядом переноса.

Формально да. Но ассемблер не обязателен.


 
Anatoly Podgoretsky ©   (2006-09-18 00:53) [13]

Ну конечно трюками можно это обойти.


 
Джо ©   (2006-09-18 01:43) [14]

С терминологией тут нелады, ИМХО. Тут циклический сдвиг обсуждается или иное?


 
Германн ©   (2006-09-18 01:49) [15]


> Anatoly Podgoretsky ©   (18.09.06 00:53) [13]
>
> Ну конечно трюками можно это обойти.
>

Почему трюками? Неужели использование множеств и директивы absolute есть большие трюки чем ASM-вставки в код паскалевской программы?


 
Германн ©   (2006-09-18 01:53) [16]


> Джо ©   (18.09.06 01:43) [14]
>
> С терминологией тут нелады, ИМХО. Тут циклический сдвиг
> обсуждается или иное?
>


Имхо, да. Если учесть

Still Swamp   (17.09.06 23:00) [4]

хм... может я сильно туплю, но еще раз. shl сдвигает без переноса сдвигаемых бит. я проверил этот факт.


 
Германн ©   (2006-09-18 01:56) [17]


> Германн ©   (18.09.06 01:53) [16]

P.S.
Имхо, да - относилось к
> Тут циклический сдвиг
> > обсуждается


 
begin...end ©   (2006-09-18 07:51) [18]

> Still Swamp   (17.09.06 23:00) [4]

Возможно, я тоже туплю. Чтобы никто из нас не тупил, давайте разбираться:

1. О каком переносе идёт речь? Что и куда должно быть перенесено?
2. Какой сдвиг нужен -- линейный (как в [1]) или циклический? Внимательно посмотрите на исходное и полученное значения в [1] -- Вам нужно это, или что-то другое?

Только без туманностей, плз. Чётко и конкретно.


 
Still Swamp   (2006-09-18 13:29) [19]

Я уже в общем выкрутился, но надо было вот такое при сдвиге влево, причем желательно без ухода в асм:
10001 -> 00011

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


 
Германн ©   (2006-09-18 14:36) [20]


> но надо было вот такое при сдвиге влево, причем желательно
> без ухода в асм:
> 10001 -> 00011

Так это же сдвиг вправо?


 
Anatoly Podgoretsky ©   (2006-09-18 15:23) [21]

Still Swamp   (18.09.06 13:29) [19]
А это уже циклический сдвиг, а не через перенос.
Через перенос будет 1.0010 + CF


 
palva ©   (2006-09-18 15:25) [22]

Так это же сдвиг вправо?
Если сдвиг циклический, то пойдешь налево, придешь направо.


 
begin...end ©   (2006-09-18 15:48) [23]

> Still Swamp   (18.09.06 13:29) [19]

Это циклический сдвиг (в приведённом примере -- циклический сдвиг 5-разрядного значения влево на 1 разряд).

В Delphi готовых средств для циклического сдвига Int64 я не встречал (хотя для 32-разрядных значений они есть), но можно сделать их самому из команд линейного сдвига. Вот пример (ROL для Int64 на 20 разрядов):

00000001001000110100010101100111  10001001101010111100110111101111  <-- исходное число (01234567 89ABCDEF)
01010110011110001001101010111100  11011110111100000001001000110100  <-- результат      (56789ABC DEF01234)


var
 I: Int64;
begin
 I := $0123456789ABCDEF;
 I := (I shr (64 - 20)) or (I shl 20);
 ShowMessageFmt("%x", [I])  <-- "56789ABCDEF01234"
end


Как видите, решение получилось в одну строчку. И без асма.


 
Still Swamp   (2006-09-18 19:17) [24]

Спасибо за науку.



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

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

Наверх




Память: 0.51 MB
Время: 0.033 c
2-1160744545
Gloomer
2006-10-13 17:02
2006.10.29
Как получить значения ключей ветки реестра?


3-1157207669
*Ray*
2006-09-02 18:34
2006.10.29
Delphi7, MySQL 5.0.18, ADO


2-1160480556
mfender
2006-10-10 15:42
2006.10.29
Интерфейсы и reinroduce


2-1160673500
Lala
2006-10-12 21:18
2006.10.29
Исключение EDBEitErrot в MaskEdit


15-1159951163
BadTester
2006-10-04 12:39
2006.10.29
Оцените, вот наднях написал программу Smart FM !!!





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский