Форум по Delphi программированию



Вернуться   Форум по Delphi программированию > Прочие языки программирования > Assembler
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 23.05.2013, 19:11
Tonyy Tonyy вне форума
Новичок
 
Регистрация: 05.04.2010
Сообщения: 85
Репутация: 10
По умолчанию своп вещественных чисел

часто сталкиваюсь с ситуацией, когда в файле содержится перевернутое число. для того чтобы число стало нормальным его байты необходимо перевернуть. в delphi для свопирования целых 2х байтных чисел есть функция swap.
для целых 4х байтных мне посчастливилось найти функцию реализованную на ассемблере:
Код:
function SwapDWorD(X:DWord):dword;assembler;
 asm
 bswap eax
 end;
не могли бы Вы мне помочь с аналогичной функцией для вещественных 4хбайтных чисел?
Ответить с цитированием
  #2  
Старый 23.05.2013, 20:09
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Самопал:
Код:
a := (a shl 24) or ((a and $FF00) shl 8) or ((a and $FF0000) shr 8) or ((a and $FF000000) shr 24);
Однако учитывая, что делфи сейчас не особо компилится под что-то отличное от x86, я бы использовал bswap, потому что такой код делфа не оптимизирует.
Можно и так:
Код:
 a := Swap(a shr 16) or (Swap(a) shl 16);
Хотя пишут, что Swap оставлен только для совместимости. Компилится чуть получше. Swap заменяется на xchg ah, al.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
Tonyy (23.05.2013)
  #3  
Старый 27.05.2013, 15:54
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

Ну если можно использовать SwapDWord, то наверно так -
Код:
SwapSingle(X:Single):Single;
var
  R:record
    case boolean of
    true:  (Y:Single);
    false: (Z:Dword); 
  end;
begin
  R.Y:=X;
  R.Z:=SwapDWorD(R.Z);
  Result:=R.Y;
end;
нету прямых команд пересылки регистр CPU<->регистр FPU
ну и до кучи
Код:
SwapDouble(X:Double):Double;
var
  R:record
    case boolean of
    true:  (Y:Double);
    false: (Z1,Z2:Dword); 
  end;
  Z:Dword;
begin
  R.Y:=X;
  Z:=SwapDWorD(R.Z1);
  R.Z1:=SwapDWorD(R.Z2);
  R.Z2:=Z;
  Result:=R.Y;
end;
Ответить с цитированием
  #4  
Старый 30.05.2013, 08:31
Аватар для Freeman
Freeman Freeman вне форума
Человек-компилятор
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 575
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Bargest
Хотя пишут, что Swap оставлен только для совместимости. Компилится чуть получше. Swap заменяется на xchg ah, al.
Эти гады вместо того, чтобы добавить перегруженные Swap для 32- и 64-битных значений, ничего не делают. 16-битный Swap, понятное дело, остался в наследство от 16-битного Turbo Pascal. В то время он еще позиционировался в том числе и в качестве системного языка.
Ответить с цитированием
  #5  
Старый 03.06.2013, 06:37
Tonyy Tonyy вне форума
Новичок
 
Регистрация: 05.04.2010
Сообщения: 85
Репутация: 10
По умолчанию

приведенные реализации, как я понял, только ведь для целых чисел, так?

а как все-таки свопировать тип single?
Ответить с цитированием
  #6  
Старый 03.06.2013, 10:41
Аватар для Freeman
Freeman Freeman вне форума
Человек-компилятор
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 575
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Tonyy
а как все-таки свопировать тип single?
Твоей функцией разве не работает? По идее, должно:
Код:
var
  S: Single;
begin
  S := Single(SwapDWord(LongWord(S));
end;
Мне проверить нечем, к сожалению.
Ответить с цитированием
  #7  
Старый 03.06.2013, 13:43
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
Сообщение от Tonyy
а как все-таки свопировать тип single?
А что понимается под свопом single? Эти числа побитово разбиты на знак, мантиссу и степень. Если просто переставить порядок байт, то получится бессмысленный бред - кусок мантиссы попадет в степень и знак, кусок степени - в мантиссу, и т.д. Если все же это нужно - загрузить число в Dword и переставить.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #8  
Старый 03.06.2013, 13:47
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Bargest
А что понимается под свопом single? Эти числа побитово разбиты на знак, мантиссу и степень. Если просто переставить порядок байт, то получится бессмысленный бред - кусок мантиссы попадет в степень и знак, кусок степени - в мантиссу, и т.д. Если все же это нужно - загрузить число в Dword и переставить.
Да, я ему уже писал об этом в этой теме.
Ответить с цитированием
  #9  
Старый 03.06.2013, 14:44
Аватар для Freeman
Freeman Freeman вне форума
Человек-компилятор
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 575
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Bargest
Если просто переставить порядок байт, то получится бессмысленный бред - кусок мантиссы попадет в степень и знак, кусок степени - в мантиссу, и т.д.
Слушай, раз такое дело, просвети: числа с плавающей запятой (IEEE) не зависят от порядка байт? Например, если я побайтно запишу в файл Single и Double на Intel, а потом прочитаю его на платформе с прямым порядком байт, я получу верное число?
Ответить с цитированием
  #10  
Старый 03.06.2013, 15:01
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Сомневаюсь. "Умники", придумавшие big-edian, по-моему его везде запихали, где только смогли. В то время как сингловый 1 хранится на х86 как 00 00 80 3F, т.е. в обратном порядке, как и остальные числа в little-edian.
И, кстати, пруф: жава юзает big-edian в .class файлах. Мне для чтения флоат-констант из файла пришлось делать
Код:
ival = bswap(*(int*)(&pData[1]));
fval = *(float*)&ival;
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 03.06.2013 в 15:04.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
Freeman (03.06.2013)
  #11  
Старый 03.06.2013, 17:28
Аватар для Freeman
Freeman Freeman вне форума
Человек-компилятор
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 575
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Bargest
И, кстати, пруф: жава юзает big-edian в .class файлах.
О, это полезная инфа, спасибо.
Ответить с цитированием
Ответ



Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 03:59.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2021

ВКонтакте   Facebook   Twitter   Ссылка на Telegram