AGB  ·  Datenschutz  ·  Impressum  







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

Assembler in Delphi! Speichersack?

Ein Thema von neolithos · begonnen am 30. Sep 2003 · letzter Beitrag vom 30. Sep 2003
Antwort Antwort
Seite 1 von 3  1 23      
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#1

Assembler in Delphi! Speichersack?

  Alt 30. Sep 2003, 11:17
Ich habe zur Übung ein Stück Quell-Code in Assembler umgewandelt.

Delphi-Quellcode:
function TColorPalette.HitColorText(apt: TPoint): Integer;
var x : Integer;
{begin
  if PtInRect(ClientRect, apt) then
    if ((apt.x mod 17) > 14) or ((apt.y mod 17) > 14) then
        Result := -1
    else
        Result := (apt.x div 17) + (apt.y div 17) * 8
  else
    Result := -1;
end;}

asm
  // apt.x div 17
  mov eax, apt.x
  mov ecx, 17
  push edx
  mov edx, 0
  div ecx
  cmp edx, 14
  jns @nowhere
  mov x, eax
  // apt.y div 17
  pop edx
  mov eax, apt.y
  mov edx, 0
  div ecx
  cmp edx, 14
  jns @nowhere
  // Result := x + y(eax) * 8
  shl eax, 3
  or eax, x
  cmp eax, 40
  jns @nowhere
  mov @Result, eax
  jmp @1
@nowhere:
  mov @Result, -1 // Result := -1
@1:
end;
Leider gibt es an einer anderen stelle im Programm ein Speicherproblem.
Wo mach ich was, was ich nicht darf?
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Assembler in Delphi! Speichersack?

  Alt 30. Sep 2003, 11:23
Das Ergebnis wird für Integer-Funktionen in EAX zurückgegeben, ansonsten kannst Du natürlich auch Result ansprechen, allerdings ohne die @ Operatoren

Code:
function TColorPalette.HitColorText(apt: TPoint): Integer;
var x : Integer;
{begin
  if PtInRect(ClientRect, apt) then
     if ((apt.x mod 17) > 14) or ((apt.y mod 17) > 14) then
        Result := -1
     else
        Result := (apt.x div 17) + (apt.y div 17) * 8
  else
     Result := -1;
end;}
asm
  // apt.x div 17
  mov eax, apt.x
  mov ecx, 17
  push edx
  mov edx, 0
  div ecx
  cmp edx, 14
  jns @nowhere
  mov x, eax
  // apt.y div 17
  pop edx
  mov eax, apt.y
  mov edx, 0
  div ecx
  cmp edx, 14
  jns @nowhere
  // Result := x + y(eax) * 8
  shl eax, 3
  or eax, x
  cmp eax, 40
  jns @nowhere
[color=#ff0000][s] mov @Result, eax[/s][/color]
  jmp @1
@nowhere:
  mov [color=#ff001b]EAX[/color], -1 // Result := -1
@1:
end;
......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#3

Re: Assembler in Delphi! Speichersack?

  Alt 30. Sep 2003, 11:31
Nach Änderung entsteht folgender Fehler...
Miniaturansicht angehängter Grafiken
dp_129.gif  
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#4

Re: Assembler in Delphi! Speichersack?

  Alt 30. Sep 2003, 11:41
Du vergisst den Stack korrekt aufzuräumen.

Delphi-Quellcode:
asm
  // apt.x div 17
  mov eax, apt.x
  mov ecx, 17
  push edx <--- hier EDX auf Stack
  mov edx, 0
  div ecx
  cmp edx, 14
  jns @nowhere <---- hier EXIT ohne EDX vom Stack zu holen
  mov x, eax
  // apt.y div 17
  pop edx <---- hier EDX vom Stack
  mov eax, apt.y
  mov edx, 0
  div ecx
  cmp edx, 14
  jns @nowhere
  // Result := x + y(eax) * 8
  shl eax, 3
  or eax, x
  cmp eax, 40
  jns @nowhere
  mov @Result, eax
  jmp @1
@nowhere:
  mov @Result, -1 // Result := -1 <----- wenn obiges JNS True ist wird EDX nicht vom Stack geholt
@1:
end;
Zudem verstehe ich nicht warum du
  Result := (apt.x div 17) + (apt.y div 17) * 8 in Assembler als
Result := (apt.x div 17) or (apt.y div 17) * 8 codiert hast.

Zudem JNS = Jump if not sign, Springe wenn EAX < 0 ! ist falsch

Delphi-Quellcode:
function TColorPalette.HitColorText(apt: TPoint): Integer;
{
var x : Integer;
begin
  if PtInRect(ClientRect, apt) then
    if ((apt.x mod 17) > 14) or ((apt.y mod 17) > 14) then
        Result := -1
    else
        Result := (apt.x div 17) + (apt.y div 17) * 8
  else
    Result := -1;
end;}

asm
     // in EAX = Self, EDX = @TPoint

   PUSH EDI
   MOV ECX,17
   MOV EAX,[EDX].TPoint.X
   MOV EDI,[EDX].TPoint.Y
   TEST EAX,EAX
   JS @@Nowhere // P.X < 0 ??
   TEST EDI,EDI
   JS @@Nowhere // P.Y < 0 ??
   XOR EDX,EDX
   DIV ECX
   CMP EDX,14
   JA @@Nowhere // P.X mod 17 > 14 ??
   XCHG EAX,EDI // EDI = P.X div 17
   XOR EDX,EDX
   DIV ECX
   CMP EDX,14
   JA @@Nowhere
   LEA EAX,[EDI + EAX * 8] // Result = P.X div 17 + P.Y div 17 * 8
   JMP @@Exit
@@Nowhere:
   XOR EAX,EAX
   DEC EAX
@@Exit
   POP EDI
end;
Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#5

Re: Assembler in Delphi! Speichersack?

  Alt 30. Sep 2003, 11:44
  MOV @Result,-1 Ist schon korrekt gewesen wenn ein lokale Stackframe eingerichtet wurde. Der Assembler macht daraus

  MOV EAX,-1 Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#6

Re: Assembler in Delphi! Speichersack?

  Alt 30. Sep 2003, 11:49
Übrigens, diese Funktion ist ein ideales Beispiel warum man noch Assembler benutzen sollte.
Denn der Delphi Compiler/Optimierer kann nicht die 4 nötigen Divisionen als 2 Divisionen codieren. Er erkennt deren Abhängigkeiten nicht. Da die Division als solches eine der langsamsten Operationen ist, ist hier ein handgemachter Assembler von Vorteil.

Man kann zwar die Division durch 17 beschleunigen, allerdings nützt das hier nicht viel da wir noch den Modulare Rest durch 17 benötigen. Dafür wiederum gibt es keine schnellere Variante als DIV, vorrausgesetzt wir benötigen den modularen Rest UND den Quotienten zu 17.

Gruß Hagen
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#7

Re: Assembler in Delphi! Speichersack?

  Alt 30. Sep 2003, 12:47
Erstmal danke für die neuen Erkenntnisse!

   JA @@Nowhere LEA EAX,[EDI + EAX * 8] // Result = P.X div 17 + P.Y div 17 * 8 Doch diese zwi Zeilen sind mir noch unklar?
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#8

Re: Assembler in Delphi! Speichersack?

  Alt 30. Sep 2003, 13:07
So ich habe gerade versucht das gegenstück zu verbessern!

Delphi-Quellcode:
function TColorPalette.GetColorRect(aiCol: Integer): TRect;
var x, y : Integer;
{begin
  if aiCol = -1 then
    Result := Rect(0, 0, 0, 0)
  else
    begin
      x := aiCol mod 8;
      y := aiCol div 8;
      Result := Rect(x * 17, y * 17, x * 17 + 14, y * 17 + 14);
    end;
end; }

asm
  push edi
  test edx, edx
  js @@nullrect // aiCol < 0
  mov edi, 8
  mov eax, edx
  xor edx, edx
  div edi // aiCol div 8
  mov x, edx // = x
  mov y, eax // = y
  mov edi, 17 // Abstand
  // berachne
  mov eax, x
  mul edi
  mov @Result.Left, eax
  mov eax, y
  mul edi
  mov @Result.Top, eax
  mov eax, x
  mul edi
  add eax, 14
  mov @Result.Right, eax
  mov eax, y
  mul edi
  add eax, 14
  mov @Result.Bottom, eax
  jmp @@exit
@@nullrect:
  mov @Result.Left, 0
  mov @Result.Top, 0
  mov @Result.Right, 0
  mov @Result.Bottom, 0
@@exit:
  pop edi
end;
Geht das noch eleganter?
Warum kann man ecx nicht nutzen
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#9

Re: Assembler in Delphi! Speichersack?

  Alt 30. Sep 2003, 13:22
Die division möchte ich nicht dur shr 3 oder and 7 ersetzen da es ja mal 9 oder n spalten werden könnten.
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#10

Re: Assembler in Delphi! Speichersack?

  Alt 30. Sep 2003, 14:28
Delphi-Quellcode:
// EAX = Self, EDX = aCol, ECX = @Result.TRect
asm
    TEST EDX,EDX
    JNS @@1
    XOR EAX,EAX
    MOV [ECX].TRect.Left,EAX
    MOV [ECX].TRect.Right,EAX
    MOV [ECX].TRect.Top,EAX
    MOV [ECX].TRect.Bottom,EAX
    RET
@@1:
    MOV EAX,EDX
    SHR EDX,3 // aCol div 8
    AND EAX,7 // aCol mod 8

    LEA EAX,[EAX * 16 + EAX] // X * 16 + X = X * 17
    LEA EDX,[EDX * 16 + EDX] // Y * 16 + Y = Y * 17

    MOV [ECX].TRect.Left,EAX
    MOV [ECX].TRect.Top,EDX
    ADD EAX,14
    ADD EDX,14
    MOV [ECX].TRect.Right,EAX
    MOV [ECX].TRect.Borrom,EDX
end;
{
JA  = Jump if Above, springe wenn größer, Vorzeichen wird ignoriert
JS  = Jump if Sign, springe wenn < 0
JNS = Jump not if Sign, springe nicht wenn < 0, bzw. springe wenn >= 0
LEA = Load Effective Address
}
Gruß Hagen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 16:14 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