![]() |
asm vergleich? (Assembler gegen delphi prog)
Hallo,
Im moment führe ich eine Addition und einen Vergleich in einer Schleife durch, um die Differenz klarer erkennen zu können (ich versuche für beide versionen die Optimalste Lösung zu erreichen und die dauer zu vergleichen. Falls ihr noch möglickeiten seht bin für jeden Hinweis dankbar). Leider funktioniert der Vergleich in assembler nicht, hat jemand eine Idee wieso? (was ich da machen will sieht man am code oder?) Code:
Delphi-Quellcode:
Gruß
unit kasm;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Button2: TButton; Label1: TLabel; Label3: TLabel; Label4: TLabel; Label7: TLabel; Label8: TLabel; Button3: TButton; Button4: TButton; Label9: TLabel; Label10: TLabel; Label2: TLabel; Label5: TLabel; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; result1,wert1,wert2,c: Integer; start1,end1:tdatetime; result2:PChar; result3:string; implementation {$R *.dfm} /////////////////////////////////////////////////////////////////////////////////////////////////// //Globale Optionen procedure TForm1.FormCreate(Sender: TObject); begin c:=1000000000; label2.Caption:=inttostr(c); label5.Caption:=inttostr(c); end; /////////////////////////////////////////////////////////////////////////////////////////////////// //Addition procedure TForm1.Button1Click(Sender: TObject); begin button1.Enabled:=false; button2.Enabled:=false; wert1:=strtoint(edit1.text); wert2:=strtoint(edit2.text); start1:=now; asm MOV ECX,c @schleife1: MOV EAX,wert1 ADD EAX,wert2 LOOP @schleife1 MOV result1,EAX end; end1:=now; label3.Caption:=inttostr(result1)+' '+Formatdatetime('ss:zzz',end1-start1); button1.Enabled:=true; button2.Enabled:=true; end; procedure TForm1.Button2Click(Sender: TObject); var i:integer; begin button1.Enabled:=false; button2.Enabled:=false; wert1:=strtoint(edit1.text); wert2:=strtoint(edit2.text); result1:=0; start1:=now; for i:=1 to c do result1:=wert1+wert2; end1:=now; label4.Caption:=inttostr(result1)+' '+Formatdatetime('ss:zzz',end1-start1); button1.Enabled:=true; button2.Enabled:=true; end; /////////////////////////////////////////////////////////////////////////////////////////////////// //Vergleich procedure TForm1.Button3Click(Sender: TObject); //var i:integer; begin button3.Enabled:=false; button4.Enabled:=false; wert1:=strtoint(edit3.text); wert2:=strtoint(edit4.text); start1:=now; asm MOV ECX,c @LO1: JMP @START @SIM: DB 'gleich',0 RET @OPP: DB 'ungleich',0 RET @START: MOV EBX,wert1 MOV EDX,wert2 CMP EBX,EDX JE @CALL LEA EDI, @OPP @CALL: LEA EDI, @SIM LOOP @LO1 MOV result2,EDI end; end1:=now; label7.Caption:=result2+' '+Formatdatetime('ss:zzz',end1-start1); button3.Enabled:=true; button4.Enabled:=true; end; procedure TForm1.Button4Click(Sender: TObject); var i:integer; begin button3.Enabled:=false; button4.Enabled:=false; wert1:=strtoint(edit3.text); wert2:=strtoint(edit4.text); start1:=now; for i:=1 to c do If wert1=wert2 then result2:='gleich' else result2:='ungleich'; end1:=now; label8.Caption:=result2+' '+Formatdatetime('ss:zzz',end1-start1); button3.Enabled:=true; button4.Enabled:=true; end; /////////////////////////////////////////////////////////////////////////////////////////////////// end. |
Re: asm vergleich? (Assembler gegen delphi prog)
Hi,
ich glaube da fehlt was:
Delphi-Quellcode:
Gruss
MOV ECX,c
@LO1: JMP @START @SIM: DB 'gleich',0 RET @OPP: DB 'ungleich',0 RET @START: MOV EBX,wert1 MOV EDX,wert2 CMP EBX,EDX JE @CALL LEA EDI, @OPP // hier überschreibst Du dir den grade geladene pointer auf den ungleich text wieder // es fehlt z.B. ein JMP @OUT @CALL: LEA EDI, @SIM @OUT: LOOP @LO1 MOV result2,EDI |
Re: asm vergleich? (Assembler gegen delphi prog)
Vielen dank für deine Antwort.
Ich verstehe was du schreibst...ich muss zugeben das ist falsch wie ich es gemacht habe....also setze nun folgenden code ein:
Delphi-Quellcode:
und erhalte folgende nachricht: "IN Projekt C:\....exe trat ein problem mit folgender Meldung auf: 'Zugriffsverletzung bei 0x0012f858: Lesen von Adresse 0x0026183b' Prozess angehalten..."
asm
MOV ECX,c @LO1: JMP @START @SIM: DB 'gleich',0 RET @OPP: DB 'ungleich',0 RET @TRUE: LEA EDI, @SIM RET @FALSE: LEA EDI, @OPP RET @START: MOV EBX,wert1 MOV EDX,wert2 CMP EBX,EDX JE @TRUE JNE @FALSE LOOP @LO1 MOV result2,EDI end; und der debugger bleibt hängen bei "0012F858 F73443 div dword ptr [ebx+eax*2]" was denkt ihr ist an dem code falsch? |
Re: asm vergleich? (Assembler gegen delphi prog)
Ich habs, es funktioniert.
das ist der Code:
Delphi-Quellcode:
Gruß
asm
JMP @START @SIM: DB 'gleich',0 @OPP: DB 'ungleich',0 @START: MOV ECX, c @LOOP: MOV EAX, wert1 CMP EAX, wert2 JZ @EQUAL LEA EDI, @OPP JMP @NEXT_LOOP @EQUAL: LEA EDI, @SIM @NEXT_LOOP: DEC ECX JNZ @LOOP MOV result2,EDI end; |
Re: asm vergleich? (Assembler gegen delphi prog)
Hallo,
mit ret springst Du nicht aus dem asm-Block, sondern aus der ganzen Prozedur. Da Du nicht aufräumst, kann hier alles mögliche passieren. Verwende ein Label in Verbindung mit einem jmp, so wie von thkerkmann vorgeschlagen. Bei Deiner inzwischen geposteten Version hat Du auch wieder das Problem, dass der Wert überschrieben wird. Gruß xaromz |
Re: asm vergleich? (Assembler gegen delphi prog)
Oh vielen dank für den Hinweis.
Was ich allerdings nicht verstehe ist, ich habe das richtige ergebnis (egal ob die ausgangswerte = oder <> zueinander sind), wenn ich also die werte überschreiben würde dann müsste ich doch zumindest bei einem a=b ausgangswert das ergebnis a<>b angezeigt bekommen weil ich den wert a=b ja mit a<>b überschreiben würde?! Ich bekomme aber bei a=b und a<>b auch das richtige ergebnis angezeigt :shock: ist es das was du meintest, oder hab ich das falsch verstanden? EDIT: ich möchte sagen, es ist doch alles ok so oder? |
Re: asm vergleich? (Assembler gegen delphi prog)
Hallo,
jetzt hab ich mir Dein Programm nochmal genauer angesehen und festgestellt, dass ich einen Denkfehler hatte. Ich dachte, dass Du in einer Schleife mehrere Werte miteinander vergleichst, aber Du vergleichst ja nur zwei Werte immer wieder. Deshalb kann es nicht sein, dass der erste Vergleich wahr ergibt und der zweite falsch. Also ist Deine Routine natürlich richtig. Gruß xaromz |
Re: asm vergleich? (Assembler gegen delphi prog)
Bitte immer die Register retten!
Es kann in einfachen Funktionen gut gehen, aber meistens geht es schief, wenn die Register nicht gerettet werden. Ausnahmen sind EAX, EDX und ECX. Die müssen nicht gerettet werden (wobei dieser Satz mit Vorsicht zu genießen ist). Das gilt allerdings auch nur, wenn du deine ganze Funktion in Assembler schreibst. Ein Mix aus Delphi und ASM in einer Funktion ist schon gefährlich genug. Allerdings würde ich da nicht auf den Compiler hoffen, dass er aufpasst, welche Register du verwendest. Edit: Was erwartest du eigentlich aus einem Vergleich? Bzw. was ist deine Vergleichsfunktion? Eine einfache Addition o.ä. ist nix, womit du den Compiler herausfordern kannst. Am Besipiel der Addition: Du willst
Delphi-Quellcode:
machen.
for i:=1 to c do result1:=wert1+wert2;
Dein Code sieht so aus:
Delphi-Quellcode:
1. Frage: Was ist wenn c<1 ist?
asm
MOV ECX,c @schleife1: MOV EAX,wert1 ADD EAX,wert2 LOOP @schleife1 MOV result1,EAX end; 2. Anmerkung: Du solltest schon das Ergebnis innerhalb der Schleife speichern, ansonsten gibt es keine entsprechende Pascal-Version, mit der du vergleichen könntest (wobei man in solchen Momenten ASM einsetzt, wenn es keine einfache Pascal-Version gibt). So, und was macht der Delphi-Compiler:
Delphi-Quellcode:
Der Unterschied liegt in dem "loop" zu "dec + jnz". Wobei mir in Erinnerung ist, dass loop langsamer ist. Das hat irgendetwas mit dem Pipelining zu tun.
asm
mov eax,c test eax,eax jle @_end @_begin: mov edx,wert1 add edx,wert2 mov result1,edx dec eax jnz @_begin @_end: end; |
Re: asm vergleich? (Assembler gegen delphi prog)
ja auf den ersten blick ist die simple addition und der vergleich schwachsin. Ich will Assembler lernen und auch verstehen lernen was mir als delphi-entwickler mit assembler für Möglichkeiten entstehen.
Deshalb ist das ein Versuch von mir, ein Delphiprogramm zu schreiben was z.b. einen vergleich in delphi und einen in assembler ausführt. Durch die Schleife (1. c kann nie < 1 sein weil es ein integer ist, und weil ich es hardcoded setze) die ich einsetze will ich die gleiche Operation, mehrmals hintereinander ausführen um so die dauer zu summieren:
Delphi-Quellcode:
Das mache ich, weil nur eine ausführung bei diesen einfachen beispielen immer in nur <001 hundertstel sec abgearbeitet wird. Damit hätte ich sogar (wie ich bisher gemerkt habe) einigermassen vergleichbare Ergebnisse zwischen dem Delphi-compiler und assembler.
start1:=now; //zeit vor der schleife
asm MOV ECX,c @schleife1: MOV EAX,wert1 ADD EAX,wert2 LOOP @schleife1 MOV result1,EAX end; end1:=now; //zeit nach der schleife label3.Caption:=inttostr(result1)+' '+Formatdatetime('ss:zzz',end1-start1); //Ergebnis + Dauer Was ich erreichen will ist, den assembler code verstehen und bei einfachen operationen am besten genauso/ähnlich schnell zu werden wie der Delphi compiler. 2. Stimmt, du hast recht, ich wollte die gespeedeste version für beide einsetzen, aber so ist das unrealistisch weil man sollte ja nicht davon ausgehen das das ergebnis immer das gleiche ist (auch wenn es in diesem fall so ist). Anmerkung umgesetzt! Das ist der asm code vom delphi compiler? cool...Vielen dank für den Tipp damit das mich das loop so ausgebremst hat (hab die ursache schon gesucht), der ist gold wert! :mrgreen: Übrigens der Code den du mir geschickt hast ist 300 hundertstel sec schneller als die schleife in delphi, ergebnis ist wiederholbar. Vielen Dank das du dir die zeit nimmst zu antworten! PS: :dp: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz