Spricht hier jemand Assembler?

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Spricht hier jemand Assembler?

Beitrag von theo »

Ich hätte einen inline asm Code (13 Zeilen) den ich gerne nach Pascal übersetzen möchte.
Traut sich das jemand zu?

_Bernd
Beiträge: 145
Registriert: Di 13. Feb 2007, 11:16

Beitrag von _Bernd »

Einfach mal posten, mal sehen.

Gruß, Bernd.

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

_Bernd hat geschrieben:Einfach mal posten, mal sehen.

Gruß, Bernd.
Danke, bin schon selber am entziffern (hab keine Ahnung von ASM).
Es ist glaub ich ganz einfach:

Hier mal der Code auf die Schnelle, schreibe nachher was ich mittlerweile weiss:

asm
push esi
mov eax, Code
mov esi, TablePtr
xor ecx, ecx
xor edx, edx
mov cl, ah
mov dl, al
mov al, [esi+ecx]
mov ah, [esi+edx]
mov ecx, 16
pop esi
sub ecx, CodeLen
shr eax, cl
mov Code, eax
end;

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Also:

move eax, Code //den longint "Code" nach eax
move esi, TablePtr //Pointer auf ByteArray nach esi
xor.... ecx und edx Null setzen
move cl, ah das tiefste Byte von ecx mit dem Hi(Lo(Code)) beschr.
move cl, ah das tiefste Byte von edx mit dem Lo(Lo(Code)) beschr.
mov al, [esi+ecx] //das Byte esi+ecx vom TablePtr nach al
mov ah, [esi+edx] //das Byte esi+edx vom TablePtr nach ah
etc pp. ;-)

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Vielleicht so?

Code: Alles auswählen

procedure what;
var ecx,edx:longint;
begin
ecx:=Hi(Word(Lo(Code)));
edx:=Lo(Word(Lo(Code)));
Code:=ByteRevTable[edx] shl 8 + ByteRevTable[ecx];
ecx:=16;
dec(ecx,Codelen);
Code := Code shr lo(lo(ecx));
end;
EDIT: Funzt!!!
Und hier das Ganze noch als Einzeiler:

Code: Alles auswählen

Code:=(ByteRevTable[Lo(Word(Lo(Code)))] shl 8 + ByteRevTable[Hi(Word(Lo(Code)))]) shr lo(lo(16-Codelen));

_Bernd
Beiträge: 145
Registriert: Di 13. Feb 2007, 11:16

Beitrag von _Bernd »

Super!

Ich hatte folgenden Ansatz:

Code: Alles auswählen

type
 Registers = record
    case i: Integer of
       0: (ax, f1, bx, f2, cx, f3, dx, f4, bp, f5, si,
          f51, di, f6, ds, f7, es, f8, flags, fs, gs : Word);
       1: (al, ah, f9, f10 ,bl ,bh ,f11 ,f12,
          cl, ch, f13, f14, dl, dh: Byte);
       2: (eax, ebx, ecx, edx, ebp, esi, edi : DWord);
    end;
 
var
   Code: DWord;
   CodeLen: DWord;
   TablePtr: Array[0..65535] of Byte;
 
procedure Unknown();
var
   Regs: Registers;
begin
   Regs.eax:= Code;
   Regs.ecx:= 0;
   Regs.edx:= 0;
   Regs.cl:= Regs.ah;
   Regs.dl:= Regs.al;
   Regs.al:= TablePtr[Regs.ecx];
   Regs.ah:= TablePtr[Regs.edx];
   Regs.ecx:= 16 - CodeLen;
   Regs.eax:= Regs.eax shr Regs.cl;
   Code:= Regs.eax;
end;
Gruß, Bernd.

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

_Bernd hat geschrieben:Super!
Ich hatte folgenden Ansatz:
Danke! Hab heute wieder was gelernt! ;-)
Ist dein Ansatz schneller? Nö, oder?

Hintergrund:
Damit läuft nun WOPR vollumfänglich (soweit wie es halt ist) auch auf 64 bit. (Siehe Anhang).
Der besprochene Teil ist im Huffman Decoder von Abbrevia Zip.
Den relevanten Teil von Abbrevia Zip habe ich nun Libc- und ASM-frei gemacht.
Dieses Package braucht es, um OpenOffice (*.odt) Dokumente zu lesen und zu schreiben.
*.odt ist ja ein Jar bzw. Zip Archiv.

Danke nochmals _Bernd
Dateianhänge
64bitwopr.png

_Bernd
Beiträge: 145
Registriert: Di 13. Feb 2007, 11:16

Beitrag von _Bernd »

theo hat geschrieben:Ist dein Ansatz schneller? Nö, oder?
nein, fast um den Faktor drei langsamer. So konnte ich aber den Assembler Code fast eins zu eins nach Pascal umsetzen, ohne mich um die Funktion des Codes kümmern zu müssen.
Ich habe jetzt noch ein paar Register einsparen können:

Code: Alles auswählen

procedure Unknown2();
var
   Regs: Registers;
begin
   Regs.al:= ByteRevTable[Hi(Code)];
   Regs.ah:= ByteRevTable[Lo(Code)];
   Code:= Regs.eax shr (16 - CodeLen);
end;
Diese Variante ist dann nicht langsamer als Deine ;-) Ich arbeite hier in einer VM, deswegen kann man da nie so ganz sicher sein mit den Messungen.
theo hat geschrieben: Hintergrund:
Damit läuft nun WOPR vollumfänglich (soweit wie es halt ist) auch auf 64 bit. (Siehe Anhang).
Gratuliere.

Mich würde aber doch noch mal interessieren, ob die Variable "Code" vom Typ "Word" ist?

Gruß, Bernd.

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

_Bernd hat geschrieben: So konnte ich aber den Assembler Code fast eins zu eins nach Pascal umsetzen, ohne mich um die Funktion des Codes kümmern zu müssen.
Interessanter Ansatz. Kann ich vielleicht mal brauchen.
Für den vorliegenden Fall bleib ich mal beim Einzeiler.
_Bernd hat geschrieben: Mich würde aber doch noch mal interessieren, ob die Variable "Code" vom Typ "Word" ist?
Longint. Hatte ich oben versteckt erwähnt (move eax, Code //den longint "Code" nach eax )

Und das macht FPC aus dem Einzeiler:

Dump of assembler code for function WHAT:
0x08048080 : push ebp
0x08048081 : mov ebp,esp
0x08048083 : movzx eax,BYTE PTR ds:0x80add34
0x0804808a : movzx eax,BYTE PTR [eax+0x80920b1]
0x08048091 : shl eax,0x8
0x08048094 : movzx edx,WORD PTR ds:0x80add34
0x0804809b : shr edx,0x8
0x0804809e : and edx,0xff
0x080480a4 : movzx edx,BYTE PTR [edx+0x80920b1]
0x080480ab : add edx,eax
0x080480ad : mov eax,edx
0x080480af : mov ecx,DWORD PTR ds:0x80add30
0x080480b5 : mov edx,0x10
0x080480ba : sub edx,ecx
0x080480bc : mov ecx,edx
0x080480be : and ecx,0xff
0x080480c4 : shr eax,cl
0x080480c6 : mov ds:0x80add34,eax
0x080480cb : leave
0x080480cc : ret
0x080480cd : lea esi,[esi]
End of assembler dump.
Zuletzt geändert von theo am Di 27. Mai 2008, 11:55, insgesamt 1-mal geändert.

_Bernd
Beiträge: 145
Registriert: Di 13. Feb 2007, 11:16

Beitrag von _Bernd »

theo hat geschrieben:
_Bernd hat geschrieben: Mich würde aber doch noch mal interessieren, ob die Variable "Code" vom Typ "Word" ist?
Longint. Hatte ich oben versteckt erwähnt (move eax, Code //den longint "Code" nach eax )
hatte ich übersehen, war ja schon spät ;-) Meine Variante müßte dann korrigiert werden:

Code: Alles auswählen

procedure Unknown2();
var
   Regs: Registers;
begin
   Regs.al:= ByteRevTable[Hi(Word(Code))];
   Regs.ah:= ByteRevTable[Lo(Code)];
   Code:= Regs.eax shr (16 - CodeLen);
end;
so, genug gespielt ;-) Schön, daß Du Deine Lösung gefunden hast.

Gruß, Bernd.

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Was ich noch erwähnen wollte: Dieses "Buch" hat mich relativ schnell auf den richtigen Weg gebracht:

http://www.hs-augsburg.de/~mraddatz/svn ... german.pdf" onclick="window.open(this.href);return false;

..falls das mal jemand brauchen kann.

Antworten