Форум: "Основная";
Текущий архив: 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