SWAP32
От: Серж  
Дата: 31.08.15 13:27
Оценка:
Здравствуйте. Есть необходимость в 32-bits слове сделать перестановку байт. Во всех доступных ресурсах есть множество готовых функций, но они, к сожалению, не подходят, потому, как меняют местами слова W0 и W1.
А мне необходимо поменять местами байты по схеме:
Исходный: b3-b2-b1-b0
SWAP: b2-b3-b0-b1
Каким способом это возможно реализовать в Delphi XE6 ?
Re: SWAP32
От: Alex.Che  
Дата: 31.08.15 13:35
Оценка:
F1: Variant parts in records
Posted via RSDN NNTP Server 2.1 beta
Re: SWAP32
От: Softwarer http://softwarer.ru
Дата: 31.08.15 13:37
Оценка: +1
Здравствуйте, Серж, Вы писали:

С>Каким способом это возможно реализовать в Delphi XE6 ?


Их столько, что трудно перечислить. Каким пробуете Вы и что у Вас не получается?
Re: SWAP32
От: LuciferSaratov Россия  
Дата: 31.08.15 13:44
Оценка:
Здравствуйте, Серж, Вы писали:

С>Каким способом это возможно реализовать в Delphi XE6 ?


для подобных вещей в паскале есть очень удобное слово absolute.
Re[2]: SWAP32
От: Серж  
Дата: 01.09.15 06:29
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Здравствуйте, Серж, Вы писали:


С>>Каким способом это возможно реализовать в Delphi XE6 ?


S>Их столько, что трудно перечислить. Каким пробуете Вы и что у Вас не получается?


Я еще не пробовал, только ищу варианты и изучаю матчасть, рассматриваю примеры.
Re[2]: SWAP32
От: Серж  
Дата: 01.09.15 10:20
Оценка: 1 (1)
Здравствуйте, LuciferSaratov, Вы писали:

LS>Здравствуйте, Серж, Вы писали:


С>>Каким способом это возможно реализовать в Delphi XE6 ?


LS>для подобных вещей в паскале есть очень удобное слово absolute.


На этом и остановился, спасибо:

function TForm1.Swap32(Value: LongWord): LongWord; //register; overload;
var
B: Byte;                      //  временный байт
WordArr: array[0..3] of byte; //  массив из 4-х байт
W: LongWord absolute WordArr; //  32-битное Word с таким же начальным адресом в памяти как и массив WordArr
begin
  W:= Value;                  //  присваиваем Word-у значение Word в котором нужно переставить местами байты
  B:= WordArr[0];             //  присваиваем временному байту значение [0] байта массива (потому что оно затрется)
  WordArr[0]:= WordArr[1];    //  присваиваем [0] байту массива значение [1] байта
  WordArr[1]:= B;             //  присваиваем [1] байту массива значение временного байта
  B:= WordArr[2];             //  аналогично...
  WordArr[2]:= WordArr[3];
  WordArr[3]:= B;
  result:= W;                 //  очень важная строка в этой функции :)
end;

Результат проверки:
Re[3]: SWAP32
От: LuciferSaratov Россия  
Дата: 01.09.15 10:46
Оценка:
Здравствуйте, Серж, Вы писали:

С>На этом и остановился, спасибо:


я бы написал как-то так:

function Swap32(V: LongWord): LongWord;
var
  a: array[0..1] of Word absolute V;
begin
  a[0] := Swap(a[0]);
  a[1] := Swap(a[1]);
  Swap32 := V;
end;
Re[4]: SWAP32
От: Alex.Che  
Дата: 01.09.15 10:54
Оценка:
> я бы написал как-то так:

если не ошибаюсь, автору нужно менять 0-й байт с 3-м, а 1-й со 2-м.
у тебя это не так.
Posted via RSDN NNTP Server 2.1 beta
Re: SWAP32
От: Aniskin  
Дата: 01.09.15 11:08
Оценка:
Здравствуйте, Серж, Вы писали:

С>Есть необходимость в 32-bits слове сделать перестановку байт.


  код
{$IFDEF CPU386}
function Swap16(AValue: Word): Word;
asm
  xchg al, ah;
end;
{$ELSE}
function Swap16(AValue: Word): Word; inline;
begin
  Result := ((AValue shr 8) and $FF) or ((AValue shl 8) and $FF00);
end;
{$ENDIF}

{$IFDEF CPU386}
function Swap32(AValue: DWORD): DWORD;
asm
  bswap eax;
end;
{$ELSE}
function Swap32(AValue: DWORD): DWORD; inline;
begin
  Result := (Swap16(AValue shr 16) and $FFFF) or ((Swap16(AValue) shl 16) and $FFFF0000);
end;
{$ENDIF}

type
  Int64Rec = packed record
    Lo, Hi: LongWord;
  end;

{$IFDEF CPU386}
function Swap64(const AValue: int64): Int64;
asm
  mov edx,dword ptr [AValue];
  mov eax,dword ptr [AValue+4];
  bswap edx;
  bswap eax;
end;
{$ELSE}
function Swap64(const AValue: int64): Int64; inline;
begin
  Int64Rec(Result).Lo := Swap32(Int64Rec(AValue).Hi);
  Int64Rec(Result).Hi := Swap32(Int64Rec(AValue).Lo);
end;
{$ENDIF}


Update: чет я затупил, прочел техзадание через строку.
Отредактировано 01.09.2015 11:30 Aniskin . Предыдущая версия .
Re[5]: SWAP32
От: LuciferSaratov Россия  
Дата: 01.09.15 11:12
Оценка:
Здравствуйте, Alex.Che, Вы писали:

>> я бы написал как-то так:


AC>если не ошибаюсь, автору нужно менять 0-й байт с 3-м, а 1-й со 2-м.

AC>у тебя это не так.

Исходный: b3-b2-b1-b0
SWAP: b2-b3-b0-b1


да вроде все так — нужно сделать Swap для слов
Re[6]: SWAP32
От: Серж  
Дата: 01.09.15 13:23
Оценка:
Здравствуйте, LuciferSaratov, Вы писали:

LS>Здравствуйте, Alex.Che, Вы писали:


>>> я бы написал как-то так:


AC>>если не ошибаюсь, автору нужно менять 0-й байт с 3-м, а 1-й со 2-м.

AC>>у тебя это не так.

LS>

LS>Исходный: b3-b2-b1-b0
LS>SWAP: b2-b3-b0-b1


LS>да вроде все так — нужно сделать Swap для слов


Нет, не для слов. Swap нужен для перестановки байт.
Как есть: 22 C5 FC 41
Как нужно: C5 22 41 FC

Порядок байт в файле-исходнике (22 C5 FC 41) — считываю байты с файла-исходника в переменную TimeW0: file (22 C5 FC 41) — SWAP и сохранение в переменную TimeW0: file (FC 41 22 C5) — записываю во вновь созданный файл (C5 22 41 FC).
Получается, что запись в файл идет зеркальная.
Re[7]: SWAP32
От: Alex.Che  
Дата: 01.09.15 13:36
Оценка:
> Получается, что запись в файл идет зеркальная.

ты мужественно пытаешься преодолеть собственные косяки в коде.
показывай как читаешь и как пишешь.
Posted via RSDN NNTP Server 2.1 beta
Re[8]: SWAP32
От: Серж  
Дата: 01.09.15 17:38
Оценка:
Здравствуйте, Alex.Che, Вы писали:

AC>ты мужественно пытаешься преодолеть собственные косяки в коде.

AC>показывай как читаешь и как пишешь.

Ошибся немножко, вот правильное трактование:
% SWAP и сохранение в переменную TimeW1: file (FC 41 22 C5) %
А вот как пишу:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
  function Swap32(Value: LongWord): LongWord;
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
  F,F1: File;
  NumRead, NumWrite: Integer;
  TimeW0,TimeW1,TimeW2: LongWord;
  Offset: Integer;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  AssignFile(F, 'C:\LOG001');
{$I-}
  Reset(F, 1);
{$I+}
  if IOResult<>0 then Halt;
  Offset := StrToInt(Edit1.Text);
  Seek(F, Offset);
  BlockRead(F, TimeW0, 4, NumRead);
  TimeW1 := Swap32(TimeW0);
  Label1.Caption := IntToStr(TimeW0);
  Label2.Caption := IntToStr(TimeW1);
  CloseFile(F);
  AssignFile(F1, 'C:\LOG001_rewrite');
{$I-}
  Rewrite(F1, 1);
{$I+}
  Seek(F1, 0);
  BlockWrite(F1, TimeW0, 4, NumWrite);
  Seek(F1, 16);
  BlockWrite(F1, TimeW1, 4, NumWrite);
  Seek(F1, 32);
  BlockWrite(F1, TimeW2, 4, NumWrite);
  CloseFile(F1);
end;

function TForm1.Swap32(Value: LongWord): LongWord;
var
B: Byte;                      //  временный байт
WordArr: array[0..3] of byte; //  массив из 4-х байт
W: LongWord absolute WordArr; //  32 битное Word с таким же начальным адресом в памяти как и массив WordArr
begin
  W := Value;                  //  присваиваем Word-у значение Word в котором нужно переставить местами байты
  B := WordArr[0];             //  присваиваем временному байту значение [0] байта массива (потому что оно затрется)
  WordArr[0] := WordArr[1];    //  присваиваем [0] байту массива значение [1] байта
  WordArr[1] := B;             //  присваиваем [1] байту массива значение временного байта
  B := WordArr[2];             //  аналогично...
  WordArr[2] := WordArr[3];
  WordArr[3] := B;
  result := W;                 
end;

end.

По умолчанию Offset := 4;
Отредактировано 01.09.2015 18:13 Серж . Предыдущая версия . Еще …
Отредактировано 01.09.2015 18:12 Серж . Предыдущая версия .
Re: SWAP32
От: Mr.Delphist  
Дата: 10.11.15 12:18
Оценка:
Здравствуйте, Серж, Вы писали:

С>Здравствуйте. Есть необходимость в 32-bits слове сделать перестановку байт. Во всех доступных ресурсах есть множество готовых функций, но они, к сожалению, не подходят, потому, как меняют местами слова W0 и W1.

С>А мне необходимо поменять местами байты по схеме:
С>Исходный: b3-b2-b1-b0
С>SWAP: b2-b3-b0-b1
С>Каким способом это возможно реализовать в Delphi XE6 ?

windows.pas содержит такие вещи как HiWord(), LoWord(), делайте над ними Swap
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.