Конференция "FreePascal" » Помогите перевести с ASM на Pascal [Win32]
 
  • П7 (19.10.04 14:42) [0]

     procedure CopySwapPixel(const Source, Destination : Pointer);
     asm
       push ebx
       mov bl,[eax+0]
       mov bh,[eax+1]
       mov [edx+2],bl
       mov [edx+1],bh
       mov bl,[eax+2]
       mov bh,[eax+3]
       mov [edx+0],bl
       mov [edx+3],bh
       pop ebx
     end;



    А то вот решил модуль портировать под FreePascal, а там ASM, в котором я не рублю...
  • Shiza (19.10.04 15:08) [1]
    Этот код лучше не переводить на Pascal :)
    А если всё-таки горит, то надо увидеть весь сырец, чтобы правильно перевести. Надо знать в каких функциях изменяются регистры ebx, eax, и определить их как переменные... но это так, на вскидку... надо код смотреть.
  • П7 (19.10.04 19:05) [2]
    Ну, можно и на FPC сразу, он ведь вроде как тоже ASM держит. Это функция из модуля Texture.pas... Позже выложу контекст, в котором эта фуцнкция применяется...
  • П7 (20.10.04 09:52) [3]
    Вот исходна функция загрузки TGA изображения. Нужно бы это всё перевести на FPC, и всем будет счастье... (:

    {------------------------------------------------------------------}
    {  Loads 24 and 32bpp (alpha channel) TGA textures                 }
    {------------------------------------------------------------------}
    function LoadTGATexture( Filename: String; var Texture: GLuint ): Boolean;
    var
     TGAHeader : packed record   // Header type for TGA images
       FileType     : Byte;
       ColorMapType : Byte;
       ImageType    : Byte;
       ColorMapSpec : Array[0..4] of Byte;
       OrigX  : Array [0..1] of Byte;
       OrigY  : Array [0..1] of Byte;
       Width  : Array [0..1] of Byte;
       Height : Array [0..1] of Byte;
       BPP    : Byte;
       ImageInfo : Byte;
     end;
     TGAFile   : File;
     bytesRead : Integer;
     image     : Pointer;    {or PRGBTRIPLE}
     CompImage : Pointer;
     Width, Height : Integer;
     ColorDepth    : Integer;
     ImageSize     : Integer;
     BufferIndex : Integer;
     currentByte : Integer;
     CurrentPixel : Integer;
     I : Integer;
     Front: ^Byte;
     Back: ^Byte;
     Temp: Byte;

     // Copy a pixel from source to dest and Swap the RGB color values
     procedure CopySwapPixel(const Source, Destination : Pointer);
     asm
       push ebx
       mov bl,[eax+0]
       mov bh,[eax+1]
       mov [edx+2],bl
       mov [edx+1],bh
       mov bl,[eax+2]
       mov bh,[eax+3]
       mov [edx+0],bl
       mov [edx+3],bh
       pop ebx
     end;

    begin
     result :=FALSE;
     GetMem(Image, 0);

     AssignFile(TGAFile, Filename);
     Reset(TGAFile, 1);

     // Read in the bitmap file header
     BlockRead(TGAFile, TGAHeader, SizeOf(TGAHeader));
     result :=TRUE;

     if Result = TRUE then
     begin
       Result :=FALSE;

       // Only support 24, 32 bit images
       if (TGAHeader.ImageType <> 2) AND    { TGA_RGB }
          (TGAHeader.ImageType <> 10) then  { Compressed RGB }
       begin
         Result := False;
         CloseFile(tgaFile);
         MessageBox(0, PChar('Couldn''t load \"'+ Filename +'\". Only 24 and 32bit TGA supported.'), PChar('TGA File Error'), MB_OK);
         Exit;
       end;

       // Don't support colormapped files
       if TGAHeader.ColorMapType <> 0 then
       begin
         Result := False;
         CloseFile(TGAFile);
         MessageBox(0, PChar('
    Couldn''t load "'+ Filename +'". Colormapped TGA files not supported.'), PChar('TGA File Error'), MB_OK);
         Exit;
       end;

       // Get the width, height, and color depth
       Width  := TGAHeader.Width[0]  + TGAHeader.Width[1]  * 256;
       Height := TGAHeader.Height[0] + TGAHeader.Height[1] * 256;
       ColorDepth := TGAHeader.BPP;
       ImageSize  := Width*Height*(ColorDepth div 8);

       if ColorDepth < 24 then
       begin
         Result := False;
         CloseFile(TGAFile);
         MessageBox(0, PChar('
    Couldn''t load "'+ Filename +'". Only 24 and 32 bit TGA files supported.'), PChar('TGA File Error'), MB_OK);
         Exit;
       end;

       GetMem(Image, ImageSize);

       if TGAHeader.ImageType = 2 then   // Standard 24, 32 bit TGA file
       begin
         BlockRead(TGAFile, image^, ImageSize, bytesRead);
         if bytesRead <> ImageSize then
         begin
           Result := False;
           CloseFile(TGAFile);
           MessageBox(0, PChar('
    Couldn''t read file "'+ Filename +'".'), PChar('TGA File Error'), MB_OK);
           Exit;
         end;

         // TGAs are stored BGR and not RGB, so swap the R and B bytes.
         // 32 bit TGA files have alpha channel and gets loaded differently
         if TGAHeader.BPP = 24 then
         begin
           for I :=0 to Width * Height - 1 do
           begin
             Front := Pointer(Integer(Image) + I*3);
             Back := Pointer(Integer(Image) + I*3 + 2);
             Temp := Front^;
             Front^ := Back^;
             Back^ := Temp;
           end;
           Texture :=CreateTexture(Width, Height, GL_RGB, Image);
         end
         else
         begin
           for I :=0 to Width * Height - 1 do
           begin
             Front := Pointer(Integer(Image) + I*4);
             Back := Pointer(Integer(Image) + I*4 + 2);
             Temp := Front^;
             Front^ := Back^;
             Back^ := Temp;
           end;
           Texture :=CreateTexture(Width, Height, GL_RGBA, Image);
         end;
       end;

       // Compressed 24, 32 bit TGA files
       if TGAHeader.ImageType = 10 then
       begin
         ColorDepth :=ColorDepth DIV 8;
         CurrentByte :=0;
         CurrentPixel :=0;
         BufferIndex :=0;

         GetMem(CompImage, FileSize(TGAFile)-sizeOf(TGAHeader));
         BlockRead(TGAFile, CompImage^, FileSize(TGAFile)-sizeOf(TGAHeader), BytesRead);   // load compressed data into memory
         if bytesRead <> FileSize(TGAFile)-sizeOf(TGAHeader) then
         begin
           Result := False;
           CloseFile(TGAFile);
           MessageBox(0, PChar('
    Couldn''t read file "'+ Filename +'".'), PChar('TGA File Error'), MB_OK);
           Exit;
         end;

         // Extract pixel information from compressed data
         repeat
           Front := Pointer(Integer(CompImage) + BufferIndex);
           Inc(BufferIndex);
           if Front^ < 128 then
           begin
             For I := 0 to Front^ do
             begin
               CopySwapPixel(Pointer(Integer(CompImage)+BufferIndex+I*ColorDepth), Pointer(Integer(image)+CurrentByte));
               CurrentByte := CurrentByte + ColorDepth;
               inc(CurrentPixel);
             end;
             BufferIndex :=BufferIndex + (Front^+1)*ColorDepth
           end
           else
           begin
             For I := 0 to Front^ -128 do
             begin
               CopySwapPixel(Pointer(Integer(CompImage)+BufferIndex), Pointer(Integer(image)+CurrentByte));
               CurrentByte := CurrentByte + ColorDepth;
               inc(CurrentPixel);
             end;
             BufferIndex :=BufferIndex + ColorDepth
           end;
         until CurrentPixel >= Width*Height;

         if ColorDepth = 3 then
           Texture :=CreateTexture(Width, Height, GL_RGB, Image)
         else
           Texture :=CreateTexture(Width, Height, GL_RGBA, Image);
       end;

       Result :=TRUE;
       FreeMem(Image);
     end;
    end;

  • PVOzerski © (20.10.04 12:33) [4]
    Начните вот с такого:
    {$asmmode Intel}
    Если после этого проблемы и останутся, все-таки с ними справиться будет легче.
  • Vladimir Vorfolomeev © (30.10.04 13:47) [5]
    Shiza   (19.10.04 15:08) [1]
    Этот код лучше не переводить на Pascal :)
    А если всё-таки горит, то надо увидеть весь сырец, чтобы правильно перевести. Надо знать в каких функциях изменяются регистры ebx, eax, и определить их как переменные... но это так, на вскидку... надо код смотреть.


    Если не знаеш ассемблер, то не пиши глупости.

    Для сведения:
     EAX - Source
     EBX - используйтся как промежуточный регистр (в начале он сохраняется а потом востанавливается)
  • Vladimir Vorfolomeev © (30.10.04 14:02) [6]
    П7

    Эту процедуру можно перевести в pascal, если надо - напиши. Но я рекомендую тебе оставить как есть, так как на pascal она будет дольше выполнятся. И по коду видно что она специально была написана на ассемблере, чтобы выполнялась быстрее.

    Если пишеш в free pascal нужно поставить дериктиву использования ассемблера синтексиса Intel, как описывал PVOzerski.
  • Vladimir Vorfolomeev © (30.10.04 14:09) [7]
    П7

    А еще, что вспомнил если в free pascal
    то будет немного по другому:

    procedure CopySwapPixel(const Source, Destination : Pointer);
    asm
      push eax
      push ebx
      mov eax, source
      mov bl,[eax+0]
      mov bh,[eax+1]
      mov [edx+2],bl
      mov [edx+1],bh
      mov bl,[eax+2]
      mov bh,[eax+3]
      mov [edx+0],bl
      mov [edx+3],bh
      pop ebx
      pop eax
    end;

    так как, только в Delphi первые три параметра передаются через регистры. Удачи тебе!
  • П7 (30.10.04 14:48) [8]
    Спасибо. Сегодня потестю... (:
    А то с директивой нужной всё откомпилилось, а толку нет. Вместо текстуры чёрный квадрат... (:
  • Vladimir Vorfolomeev © (30.10.04 14:59) [9]
    Сорри, я забыл destination добавить в регистр, вот правильный листинг

    procedure CopySwapPixel(const source, destination: Pointer);
    asm
     push eax
     push edx
     push ebx
     mov eax, source
     mov edx, destination
     mov bl,[eax+0]
     mov bh,[eax+1]
     mov [edx+2],bl
     mov [edx+1],bh
     mov bl,[eax+2]
     mov bh,[eax+3]
     mov [edx+0],bl
     mov [edx+3],bh
     pop ebx
     pop edx
     pop eax
    end;
  • Vladimir Vorfolomeev © (30.10.04 15:02) [10]
    а лучше перевести в родной синтаксис AT&T для free pascal.
    будет меньше проблем.

    сегодня вечером переведу, если надо
  • Vladimir Vorfolomeev © (30.10.04 15:34) [11]
    можеш попробывать и это, но без дериктивы {$asmmode Intel}
    Но мне кажется в самой процедуре какая та ошибка

    procedure CopySwapPixel(const Source, Destination: Pointer);
    asm
    movl $source, %eax
    movl $destination, %edx
      movb 0(%eax), %bl
    movb 1(%eax), %bh
    movb %bl, 2(%edx)
    movb %bh, 1(%edx)
    movb    2(%eax), %bl
    movb 3(%eax), %bh
    movb    %bl, 0(%edx)
    movb %bh, 3(%edx)
    end ['EAX','EBX','EDX'];
  • PVOzerski © (01.11.04 09:14) [12]
    Ребята, имейте в виду вот какую вещь. В нестабильной (разрабатываемой) версии 1.9.x на этапе какого-то из снапшотов было в 2 этапа осуществлено изменение соглашений о передаче параметров по умолчанию. Сначала (как это и есть в 1.0.x) это был упрощенный stdcall, потом - stdcall с сохранением части регистров согласно спецификации и, наконец, register как в Delphi. Сами понимаете, если мы пишем обращение к параметрам на асме, уходя от использования имен переменных, это может быть критично. Конечно, номера соответствующих билдов компилятора я уже не помню и восстановить их не берусь. Во всяком случае, проверьте, с чем имеете дело (хотя бы путем генерации asm-кода).
  • Sapersky (01.11.04 16:28) [13]
    функция загрузки TGA изображения. Нужно бы это всё перевести на FPC, и всем будет счастье

    Загрузка TGA на Паскале (без asm) есть в PowerDraw (в 2.80 во всяком случае). Там, конечно, грузится в какой-то свой класс, но переделать недолго.
  • frame © (02.02.05 01:50) [14]
    >procedure CopySwapPixel(const source, destination: Pointer);
    >asm
    >.....
    Раз первые два паремтра передаются в регистры, то
    > mov eax, source
    > mov edx, destination можно вобще не писать!
    и правильно описание должно так выглядеть:
    procedure CopySwapPixel(source, destination: Pointer), чтобы Source и Destination содержали ЗНАЧЕНИЯ, а не адресы.
  • thaddy (11.02.05 14:35) [15]
    // not shure about fpc but in delphi it would be:
    procedure CopySwapPixel(const Source, Destination : Pointer);
    var
     SrcPix :array[0..3]  of Byte absolute Source;
     DestPix:array[0..3] of byte  absolute Destination;
    begin
     DestPix[3]:=SrcPix[0];
     DestPix[2]:=SrcPix[1];
     DestPix[1]:=SrcPix[2];
     DestPix[0]:=SrcPix[3];
    end;
  • thaddy (11.02.05 15:11) [16]
    Better:
    call should remove const and be var with type cardinal, not pointer
  • VoRoN (17.11.08 18:32) [17]

    > PVOzerski ©   (20.10.04 12:33) [4]
    > Начните вот с такого:{$asmmode Intel}Если после этого проблемы
    > и останутся, все-таки с ними справиться будет легче.

    хороший совет, очень помогло :) час не мог ошибку найти
    первый раз на фри паскале сижу, перешел с делфи
  • имя (04.04.09 01:54) [18]
    Удалено модератором
  • имя (04.04.09 01:54) [19]
    Удалено модератором
 
Конференция "FreePascal" » Помогите перевести с ASM на Pascal [Win32]
Есть новые Нет новых   [118685   +14][b:0][p:0.007]