Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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


Страницы:   1 2

Still Swamp ©   (2006-09-17 19:21:00) 

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


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

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


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

> 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 22:13:00) [23]

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


begin...end   (2006-09-17 20:25:00) [24]

Не совсем понял, о каком переносе идёт речь. Если имеется в виду обычный линейный сдвиг 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 (сдвиг для которого реализован, кстати, по описанному принципу) и не мучаться.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо