AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Rgb mittels Asm darstellen

Ein Thema von thomasku · begonnen am 4. Mai 2009 · letzter Beitrag vom 7. Mai 2009
Antwort Antwort
Seite 1 von 2  1 2      
thomasku

Registriert seit: 4. Jan 2009
31 Beiträge
 
#1

Rgb mittels Asm darstellen

  Alt 4. Mai 2009, 01:42
Hallo,

Ich möchte gern die rgb Funktion mittels assemblercode darstellen.
Delphi-Quellcode:
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;
MIt dieser bekomme ich zwar ein ähnliches Ergebnis, allerdings dunkler(wobei beides integer, a 8 Bit sind).
Siehe dazu Bild.
Folgende Funktion hatte ich ursprünglich, hier erhalte ich aber nur einen teil.
Delphi-Quellcode:
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;
Mfg thomas
Angehängte Grafiken
Dateityp: bmp rgb_vs_asm_178.bmp (264,3 KB, 21x aufgerufen)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#2

Re: Rgb mittels Asm darstellen

  Alt 4. Mai 2009, 05:11
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.)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
thomasku

Registriert seit: 4. Jan 2009
31 Beiträge
 
#3

Re: Rgb mittels Asm darstellen

  Alt 4. Mai 2009, 05:23
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
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: Rgb mittels Asm darstellen

  Alt 4. Mai 2009, 05:27
Ahhhh okay, danke
Was das Problem an sich angeht... da hätte ich wohl die Nacht besser nicht durchgemacht *hust* Ich seh nur noch Matsche aufm Bildschirm, au ha.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: Rgb mittels Asm darstellen

  Alt 4. Mai 2009, 06:38
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:
sub edx,eax;
    Mov result,Eax;
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...
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.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
thomasku

Registriert seit: 4. Jan 2009
31 Beiträge
 
#6

Re: Rgb mittels Asm darstellen

  Alt 4. Mai 2009, 07:57
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:
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;
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.

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
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Rgb mittels Asm darstellen

  Alt 4. Mai 2009, 08:04
Schreib das einfach so:
Delphi-Quellcode:
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;
Die Parameter liegen der Reihe nach in EAX, EDX und ECX, danach auf dem Stack. Das Ergebnis gehört in EAX.

(Ausnahme wäre ein String als Rückgabewert. Dabei wird der String für das Ergebnis wie ein weiterer Parameter übergeben.)
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
thomasku

Registriert seit: 4. Jan 2009
31 Beiträge
 
#8

Re: Rgb mittels Asm darstellen

  Alt 4. Mai 2009, 08:17
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
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#9

Re: Rgb mittels Asm darstellen

  Alt 4. Mai 2009, 09:28
Delphi-Quellcode:
function farbverlauf2(rot,gruen:integer):TColor;
begin
  ASM
    @kalt:
      sub edx,eax;
erstmal das Begin-End ... darum wird doch bestimmt ein "unnötiger" Stackframe erstellt
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

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:
function farbverlauf2(rot, gruen: Integer): TColor;
begin
  if rot < gruen then result := rot - gruen
  else result := (gruen - rot) shl 8;
end;
unten im Bild:
Code:
[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]
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.
Delphi-Quellcode:
function farbverlauf2(rot, gruen: Integer): TColor; Inline;
begin
  if rot < gruen then result := rot - gruen
  else result := (gruen - rot) shl 8;
end;
[edit]
ups, Bild vergessen

[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"


[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 )
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;
Miniaturansicht angehängter Grafiken
unbenannt_920.jpg  
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
thomasku

Registriert seit: 4. Jan 2009
31 Beiträge
 
#10

Re: Rgb mittels Asm darstellen

  Alt 7. Mai 2009, 10:22
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.
Mov ebp,esp //lade Stack pointer in Base pointer Result erzeugt glaube ebenfalls einen;
Add esp, $0c jedoch sehe ich nicht die Notwendigkeit
(rechte Seite des Bildes) von:
push ecx //ablegen von ecx auf dem stack Der Result- STackframe dient doch dann der Sicherung, ist er wirklich unnötig?
Zu mind. solange man noch nicht weiß ob der Code funktioniert.
(Ich habe es nicht nur einmal geschafft Delphi zum abstürzen zu bringen )


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:
http://www.delphipraxis.net/internal...ct.php?t=94005

An den negativen Werten arbeite ich noch.

Mfg Thomas
Miniaturansicht angehängter Grafiken
tasm_559.jpg  
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz