Widergabewert eines CustomTypes mit Assembler

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
Antworten
Key-Real
Beiträge: 10
Registriert: Sa 28. Sep 2013, 23:36

Widergabewert eines CustomTypes mit Assembler

Beitrag von Key-Real »

Code: Alles auswählen

type
               gfxImage = packed record
                data : pointer;
                width, height : dword;
               end;
               gfxColor = packed record
                b,g,r,a:byte;
               end;
 
 
    function GetColor(where:gfxImage;x,y:dword):gfxColor;
    assembler;
    asm
         imul ecx,dword ptr [eax+4]
 
          add ecx,edx
          shl ecx,2
          add ecx,[eax]
 
          mov eax,dword ptr [ecx]
          // where to move eax to get the color in the function result ???
    end;
 
    {    // This works
    var c:gfxColor;
    begin
     system.move(pdword(where.data+(y*where.width+x) shl 2)^,c,4);
     getcolor:=c;
    end;
    }

 




Bei einem StandartType müsste man den Rückgabewert in EAX schreiben, z.B. wenn man ein DWORD zurückgibt schreibt man einfach den Wert den man zurückgeben möchte in EAX. Aber wie ist es mit einem benutzerdifeniertem Typus?
Zuletzt geändert von Lori am So 6. Okt 2013, 12:06, insgesamt 1-mal geändert.
Grund: Highlighter

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Widergabewert eines CustomTypes mit Assembler

Beitrag von Michl »

Evtl. so: ?!

Code: Alles auswählen

function GetColor(where:gfxImage;x,y:dword):gfxColor; assembler;
asm
  imul ecx,dword ptr [eax+4]
 
  add ecx,edx
  shl ecx,2
  add ecx,[eax]
 
  mov eax,dword ptr [ecx]
  mov Result,eax
 
end;

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Key-Real
Beiträge: 10
Registriert: Sa 28. Sep 2013, 23:36

Re: Widergabewert eines CustomTypes mit Assembler

Beitrag von Key-Real »

Funktioniert leider so nicht :(
und wenn dann braucht man {$MODE OBJFPC}, geht aber trotzdem nicht

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Widergabewert eines CustomTypes mit Assembler

Beitrag von Michl »

Ich habe getestet unter {$mode delphi}!

Und der Test

Code: Alles auswählen

function GetColor(where:gfxImage;x,y:dword):gfxColor; assembler;
asm
  imul ecx,dword ptr [eax+4]
 
  add ecx,edx
  shl ecx,2
  add ecx,[eax]
 
  mov eax,dword ptr [ecx]
  mov Result,eax
end;
 
function GetColor2(where:gfxImage;x,y:dword):gfxColor;
var
  c:gfxColor;
begin
  system.move(pdword(where.data+(y*where.width+x) shl 2)^, c, 4);
  Result:=c;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  g:gfxImage;
  c:gfxColor;
const
  x:integer=0;
begin
  g.data:=Image1.Picture.Bitmap.RawImage.Data;
  g.height:=Image1.Picture.Bitmap.Height;
  g.width:=Image1.Picture.Bitmap.Width;
 
  c:=GetColor(g, x, 0);
  Caption:=inttostr(c.r)+' - '+inttostr(c.g)+' - '+inttostr(c.b)+' - '+inttostr(c.a);
 
  c:=GetColor2(g, x, 0);
  Caption:=Caption+'  Zum Vergleich:  '+inttostr(c.r)+' - '+inttostr(c.g)+' - '+inttostr(c.b)+' - '+inttostr(c.a);
 
  inc(x);
end;
liefert bei mir identische Werte, sollte also gehen!

FPC + Assembler + verschiedene Zielsysteme sollte man allerdings vermeiden.

[Edit] Wobei bei dem von mir getesteten RawImage kein Alpha-Kanal dabei ist und somit nur 3 Byte ausgelesen werden müssten. Daher wäre das Offset mit 3 Bytes zu berechnen...

Code: Alles auswählen

function GetColor(where:gfxImage;x,y:dword):gfxColor; assembler;
asm
  imul ecx,dword ptr [eax+4]
 
  add ecx,edx
  imul ecx,3
  add ecx,[eax]
 
  mov eax,dword ptr [ecx]
  mov Result,eax
end;
 
function GetColor2(where:gfxImage;x,y:dword):gfxColor;
var
  c:gfxColor;
begin
  system.move(pdword(where.data+(y*where.width+x)*3)^, c, 4);
  Result:=c;
end

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Key-Real
Beiträge: 10
Registriert: Sa 28. Sep 2013, 23:36

[solved] Widergabewert eines CustomTypes mit Assembler

Beitrag von Key-Real »

So hats funktioniert:

Code: Alles auswählen

{$MODE OBJFPC}
unction GetColor(where:gfxImage;x,y:dword):gfxColor;
assembler;
asm
     imul ecx,dword ptr [eax+4]
 
      add ecx,edx
      shl ecx,2
      add ecx,[eax]
 
      mov eax,dword ptr [ecx]
      mov ecx,result
      mov [ecx],eax
end;



unter {$MODE OBJFPC} funktioniert es nur so. (Ich benutze die 2.6.2 Version von FPC, kein LAZARUS).
Danke Michl, deine Idee mit RESULT hat mich wietergebracht :)

so wie du es beschreibst wundert es mich das es ging... habe auch unter {$MODE DELPHI} versucht, ging aber so nicht.

das ding ist wenn ich in Variablen im HEader einer Function schreiben will muss ich "das gleiche" machen, z.B:

Code: Alles auswählen

Procedure getRGBA(col:dword;var r,g,b,a:byte);
assembler;
asm
 
   mov edi,b
   mov byte ptr [edi],al
 
   mov edi,g
   mov byte ptr [edi],ah
 
   shr eax,16
 
   mov edi,r
   mov byte ptr [edi],al
 
   mov edi,a
   mov byte ptr [edi],ah
 
end;
 


Gruß,
Kirill
Zuletzt geändert von Lori am So 6. Okt 2013, 12:07, insgesamt 2-mal geändert.
Grund: Bitte den Highlighter nutzen

Antworten