![]() |
Rgb mittels Asm darstellen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
Ich möchte gern die rgb Funktion mittels assemblercode darstellen.
Delphi-Quellcode:
MIt dieser bekomme ich zwar ein ähnliches Ergebnis, allerdings dunkler(wobei beides integer, a 8 Bit sind).
function farbverlauf1(rot,gruen:integer):TColor;
begin if rot < gruen then result:=rgb(rot-gruen,0,0) else result:=rgb(0,gruen-rot,0); {$R *.dfm} end; function farbverlauf2(rot,gruen:integer):TColor; begin ASM Mov Eax,rot; //init Mov Edx,gruen; CMP Eax,edx; jns @kalt; //rot<gruen sub edx,eax; Mov result,Eax; jmp @weiter; @kalt: sub edx,eax; shl eax,8; Mov result,Eax; @weiter: end; end; procedure TForm1.Button1Click(Sender: TObject); Var x,y:integer; begin For x:=0 to 255 do For y:=0 to 255 do Image1.Canvas.Pixels[x,y]:=farbverlauf2(x,y); Image1.Update; end; Siehe dazu Bild. Folgende Funktion hatte ich ursprünglich, hier erhalte ich aber nur einen teil.
Delphi-Quellcode:
Mfg thomas
function farbverlauf2(rot,gruen:integer):TColor;
begin ASM Mov Eax,rot; //init Mov Edx,gruen; CMP Eax,edx; jns @kalt; //rot<gruen sub eax,edx; Mov result,Eax; jmp @weiter; @kalt: sub edx,eax; shl eax,8; Mov result,Eax; @weiter: end; end; |
Re: Rgb mittels Asm darstellen
Ohne jetzt explizit auf das Problem einzugehen: Wenn es dir hierbei um einen Geschwindigkeitsvorteil geht (und 8 Bit/Kanal ausreichen), sollte es sich für dich lohnen wenn du dir den MMX Befehlssatz mal anschaust.
Mir ist ausserdem gerade schleierhaft inwiefern deine Farbverlaufsmethode sinnvoll eingesetzt werden könnte - darf man fragen wozu du sie brauchst? (Reines Interesse, keine subtile Kritik.) |
Re: Rgb mittels Asm darstellen
Hallo Medium und vielen Dank,
Nein um Geschwindigkeit oder irgendeinen anderen multimedialen Einsatz geht es mir nicht. Die Aufgabe habe ich in dieser Art gestellt bekommen. Der Sinn ist die Einbindung von Assemblerbefehlen in Delphi. Dienen soll es der Darstellung von Temperaturen, rot=warm... Mfg thomas |
Re: Rgb mittels Asm darstellen
Ahhhh okay, danke :)
Was das Problem an sich angeht... da hätte ich wohl die Nacht besser nicht durchgemacht *hust* :stupid: Ich seh nur noch Matsche aufm Bildschirm, au ha. |
Re: Rgb mittels Asm darstellen
Was mir auffällt ist erst einmal: Wozu legst du die Parameter in eax und edx? Da sind die doch eh schon drin...
Mach lieber eine komplette Assemblerroutine draus, dann sparst du dir das. Zum Fehler:
Delphi-Quellcode:
Du subtrahierst von edx (gruen) den Inhalt von eax (rot), also gruen - rot, und das ist dann in edx. Danach packst du den Inhalt von eax (rot) in Result... ;-)
sub edx,eax;
Mov result,Eax; Du hast die Parameter für sub vertauscht. Vor allem machst du ja die selbe Subtraktion für beide Fälle und benutzt danach immer das (unveränderte) eax. |
Re: Rgb mittels Asm darstellen
Morgen jaenicke und vielen Dank,
Hatte schon im ersten Post sowie in meinem Programm einen Fehler. rot < gruen => rot>gruen und mit deinen Tipps, habe ich nun auch das selbige raus. vollstaendigkeits- halber der Code:
Delphi-Quellcode:
Momentan sehe ich zwar noch nicht warum ich nicht die selbe Grafik erhalte, wenn ich wie oben, in farbverlauf1 das Relationszeichen drehe und in farbverlauf2 aus js =>jns mache, allerdings bin ich erstmal sehr froh das es klappt. :lol:
function farbverlauf1(rot,gruen:integer):TColor;
begin if rot > gruen then result:=rgb(rot-gruen,0,0) else result:=rgb(0,gruen-rot,0); {$R *.dfm} end; function farbverlauf2(rot,gruen:integer):TColor; begin ASM Mov Eax,rot; //init Mov Edx,gruen; CMP Eax,edx; js @kalt; //rot<gruen sub eax,edx; Mov result,Eax; jmp @weiter; @kalt: sub edx,eax; shl edx,8; Mov result,Edx; @weiter: end; end; Ich habe keine eigene Routine gemacht, weil ich noch nicht weiß wie dies geht. Ich mache derzeit meine ersten Gehversuche mit der Assemblereinbindung. Mfg thomas |
Re: Rgb mittels Asm darstellen
Schreib das einfach so:
Delphi-Quellcode:
Die Parameter liegen der Reihe nach in EAX, EDX und ECX, danach auf dem Stack. Das Ergebnis gehört in EAX.
function farbverlauf2(rot, gruen: integer): TColor;
asm cmp eax, edx; js @kalt; //rot<gruen sub eax, edx; jmp @weiter; @kalt: sub edx, eax; shl edx, 8; mov eax, edx; @weiter: end; (Ausnahme wäre ein String als Rückgabewert. Dabei wird der String für das Ergebnis wie ein weiterer Parameter übergeben.) |
Re: Rgb mittels Asm darstellen
Danke nochmal,
Achso dann muss ich wohl leider zugeben, dass ich doch schon einmal etwas davon gehört habe. (Mit Stackframe bzw ohne, dachte immer mit ist die sichere Variante) Ich werde mich nochmal intensiver damit beschäftigen. Mfg thomas |
Re: Rgb mittels Asm darstellen
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
erstmal das Begin-End ... darum wird doch bestimmt ein "unnötiger" Stackframe erstellt
function farbverlauf2(rot,gruen:integer):TColor;
begin ASM @kalt: sub edx,eax; und durch die nutzung von Result (mittendrin) ebenfalls ... dort wird Result<>EAX bestimmt sein, da zwischendurch eine Temp-Variable für Result eingerichtet und diese erst am Ende nach EAX kopiert wird. außerdem wozu rechnest du da mit EDX, wo du EDX danach eh nichtmehr verwendest? bei kalt also überall statt eax ein edx verwenden :zwinker: und wenn das ASM richtig genutzt würde (ohne delphis Stackframe), dann wäre Mov result,Eax; eh "nutzlos", da Result=EAX. also ich würde mal stark vermuten, daß 'ne compileroptimierte Variante am Ende sogar schneller/optimaler arbeitet, als dieser ASM-Code. [add] *ins Bild guck* ... stümmt [/add] PS: jns @kalt; im High-Byte ist ein Steurbyte (bei der GDI für die verwendete Farboalette) und keine der Farben Rot oder Grün, also hat dieser Vergleich nichts mit Rot-Grün zu tun. oben im Bild:
Delphi-Quellcode:
unten im Bild:
function farbverlauf2(rot, gruen: Integer): TColor;
begin if rot < gruen then result := rot - gruen else result := (gruen - rot) shl 8; end;
Code:
und in einem "neueren" Delphi, wo Inline-Funktionen unterstütz werden, wäre dieses das optimalste, da dort nichtmal erst 'ne Funktion angelegt, sondern der Code direkt an der aufrufenden Stelle eingefügt würde. :angel:
[b]function[/b] farbverlauf2(rot,gruen:integer):TColor;
[b]begin[/b] [b]ASM[/b] Mov Eax,rot //init Mov Edx,gruen CMP Eax,edx jns @kalt //rot<gruen sub eax,edx Mov result,Eax jmp @weiter @kalt: sub edx,eax shl [color=#ff0000]edx[/color], 8 Mov result, [color=#ff000]Edx[/color] @weiter: [b]end;[/b] [b]end;[/b]
Delphi-Quellcode:
[edit]
function farbverlauf2(rot, gruen: Integer): TColor; Inline;
begin if rot < gruen then result := rot - gruen else result := (gruen - rot) shl 8; end; ups, Bild vergessen :oops: [add] und wenn ich mir den Code von jaenicke anseh ... bis auf jmp @weiter;, welches in 'ner kleinem RET kürzer wär ... ist's schonmal ein sehr großer Fortschritt, gegenüber dem "Original" :angel2: [add2] was du eigentlich meintest war: (sobald du für rot und gruen mal 'nen Wert außerhalb von 0..255 übergibst, wirst du den Unterschied erkennen :wink: )
Delphi-Quellcode:
function farbverlauf1(rot, gruen: Byte): TColor;
begin if rot < gruen then result := rgb(rot - gruen, 0, 0) else result := rgb(0, gruen - rot, 0); end; function farbverlauf2(rot, gruen: Byte): TColor; ASM cmp al, dl jns @kalt sub al, dl and eax, $0000ff ret @kalt: sub eax, edx xor eax, eax // statt and eax, $00ff00 mov ah, dl //and eax, $00ff00 end; |
Re: Rgb mittels Asm darstellen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo himitsu und vielen Dank,
ich habe mir ebenfalls mal die Cpu-Fenster meiner Funktion farbverlauf2 (aus Beitrag6)anzeigen lassen. (Vgl Tasm.jpg) Das sind einmal die Funktion mit Begin und End und das andere mal ohne. Meiner Meinung nach legen aber beide Funktionen einen Stackframe an.
Delphi-Quellcode:
Result erzeugt glaube ebenfalls einen;
Mov ebp,esp //lade Stack pointer in Base pointer
Delphi-Quellcode:
jedoch sehe ich nicht die Notwendigkeit
Add esp, $0c
(rechte Seite des Bildes) von:
Delphi-Quellcode:
Der Result- STackframe dient doch dann der Sicherung, ist er wirklich unnötig?
push ecx //ablegen von ecx auf dem stack
Zu mind. solange man noch nicht weiß ob der Code funktioniert. (Ich habe es nicht nur einmal geschafft Delphi zum abstürzen zu bringen :mrgreen: ) Zur Schnelligkeit, es ist wie gesagt nur ein Bsp an den wir den Umgang mit Asm üben sollen. Woran erkennt man denn, welches Programm schneller arbeitet, ohne explizit zu testen? Am Umfang der elementar Operationen? Habe mir auch schon das Tutorial hierzu durchgelesen: ![]() An den negativen Werten arbeite ich noch. Mfg Thomas |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:46 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