Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Byte an bestimmter Speicherposition mit Assembler löschen (https://www.delphipraxis.net/114752-byte-bestimmter-speicherposition-mit-assembler-loeschen.html)

Cyf 30. Mai 2008 17:43


Byte an bestimmter Speicherposition mit Assembler löschen
 
Wäre wirklich schön, wenn mir damit jemand helfen könnte, der sich besser damit auskennt.
Ich habe mich mal daran gemacht einige Assemblerfunktionen zu schreiben, um ein wenig dazuzulernen, ob asm bei so etwas sinnvoll ist, sei mal dahin gestellt.
Folgende Funktion soll zusammenhängendes Byte einer Variable oder Instanz löschen (mit 0 füllen).

Delphi-Quellcode:
procedure ByteLoeschen(p: Pointer; Index: Byte); assembler;
asm
  mov EDX, 0FFFFFF00h
  mov CL, BL
  sal Cl, 3  //Linksverschiebung mit Anhängen von Nullen, *2*2*2
  STC //setze Carry-Flag, um kein Bit zu verlieren
  rcl EDX, CL //Rechtsverschuebung mit Anhängen des Carry-Flags, setzt Carry-Flag
  and [EAX], EDX
end;
Das Ganze funktioniert so weit auch ganz gut, meine Frage ist mehr, ob diese Lösung effektiv ist, oder wie "der übliche Weg" für so etwas aussieht (ohne im Pointer gleich den Anfang des zu löschenden Bytes zu übergeben). asm wird ja normalerweise nur benutzt, um Code möglichst effektiv zu gestalten.

3_of_8 30. Mai 2008 17:46

Re: Byte an bestimmter Speicherposition mit Assembler lösche
 
Also wenn du ein Byte an einer bestimmten Speicherstelle löschen willst, warum benutzt du dann nicht einfach mov dword ptr eax, 0?

Apollonius 30. Mai 2008 17:50

Re: Byte an bestimmter Speicherposition mit Assembler lösche
 
Wohl eher Byte ptr eax.
@CyF: Funktioniert das? Der zweite Parameter liegt in dl, nicht bl.

Cyf 30. Mai 2008 18:06

Re: Byte an bestimmter Speicherposition mit Assembler lösche
 
Hab die ganze Teit eine Methode gesucht was anderes als 32-Bit Blöcke zu schreiben und hab eine Möglichkeit gesucht es trotzdem zu schaffen... hmm naja, warum auch einfach. :wink:

Habs mal so ersetzt:

Delphi-Quellcode:
procedure ByteLoeschen2(p: Pointer; Index: Byte); assembler;
asm
  mov Byte [EAX + EBX], 0
end;
Dabei scheint es erstaunlicherweiße egal zu sein, ob ich EBX oder EDX nehme, funktioniert beides, was mich etwas verwirrt.
Man sollte aber normalerweiße das 'D'-Register für das 2te Argument nehmen?

Was genau ist mit 'prt' eax gemeint?

3_of_8 30. Mai 2008 18:07

Re: Byte an bestimmter Speicherposition mit Assembler lösche
 
Natürlich, byte ptr, ich war jetzt irgendwie auf Cardinal...

byte ptr heißt einfach, dass man nicht in EAX schreibt, sondern auf das Byte, das EAX referenziert.

Apollonius 30. Mai 2008 18:08

Re: Byte an bestimmter Speicherposition mit Assembler lösche
 
Kannst du mal zeigen, wie du deine Funktion aufrufst? Denn EBX zu verwenden ist garantiert falsch.
BYTE PTR EAX ist das selbe wie [EAX], nur das zusätzlich klargestellt wird, dass EAX auf ein Byte und nicht etwa auf ein Word, Dword oder sonstiges zeigt.

Cyf 30. Mai 2008 18:16

Re: Byte an bestimmter Speicherposition mit Assembler lösche
 
Hier mal der Quelltext der ganzen Unit:

Delphi-Quellcode:
unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    BLoeschen: TButton;
    EZahl: TEdit;
    EZahlHex: TEdit;
    EGeloescht: TEdit;
    EGeloeschtHex: TEdit;
    LByte: TLabel;
    EByte: TEdit;
    procedure BLoeschenClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

procedure ByteLoeschen(p: Pointer; Index: Byte);
procedure ByteLoeschen2(p: Pointer; Index: Byte);

var
  Form1: TForm1;

implementation

procedure ByteLoeschen(p: Pointer; Index: Byte); assembler;
asm
  mov EDX, 0FFFFFF00h
  mov CL, BL
  sal Cl, 3  //Linksverschiebung mit Anhängen von Nullen, *2*2*2
  STC //setze Carry-Flag, um kein Bit zu verlieren
  rcl EDX, CL //Rechtsverschuebung mit Anhängen des Carry-Flags, setzt Carry-Flag
  and [EAX], EDX
end;

procedure ByteLoeschen2(p: Pointer; Index: Byte); assembler;
asm
  mov Byte [EAX + EBX], 0
end;

{$R *.dfm}

procedure TForm1.BLoeschenClick(Sender: TObject);
var IntZahl: Integer; ByteNr: Shortint;
begin
  try
    IntZahl:= StrToInt(EZahl.Text);
    ByteNr:= StrToInt(EByte.Text) - 1;
    if((IntZahl < 0) or (ByteNr < 0) or (ByteNr > 3)) then begin
      raise Exception.Create('Ungültiger Wert!');
    end;
    EZahlHex.Text:= IntToHex(IntZahl, 1);
    ByteLoeschen2(@IntZahl, ByteNr);
    EGeloescht.Text:= IntToStr(IntZahl);
    EGeloeschtHex.Text:= IntToHex(IntZahl, 1);
  except
    ShowMessage('Ungültiger Wert!');
  end;
end;

end.
Wenn dadurch klar wird, warum der zweite Parameter auch in EBX liegt, lasst es mich wissen.

Chemiker 30. Mai 2008 18:46

Re: Byte an bestimmter Speicherposition mit Assembler lösche
 
Hallo Cyf,

die Register EAX, ECX und EDX stehen unter Delphi zur freien Verfügung. Willst Du die anderen Register verwenden, so sollte man sie vor der Veränderung auf den Stack packen und vor dem Verlassen in den ursprünglichen Zustand wieder herstellen.

Bis bald Chemiker

Cyf 30. Mai 2008 19:08

Re: Byte an bestimmter Speicherposition mit Assembler lösche
 
Delphi-Quellcode:
procedure ByteLoeschen(p: Pointer; Index: Byte); assembler;
asm
  mov CL, DL
  mov EDX, 0FFFFFF00h
  sal Cl, 3  //Linksverschiebung mit Anhängen von Nullen, *2*2*2
  STC //setze Carry-Flag, um kein Bit zu verlieren
  rcl EDX, CL //Rechtsverschuebung mit Anhängen des Carry-Flags, setzt Carry-Flag
  and [EAX], EDX
end;

procedure ByteLoeschen2(p: Pointer; Index: Byte); assembler;
asm
  mov Byte [EAX + EDX], 0
end;
Funktionen sind nun so verändert, dass sie EBX nicht mehr verwenden (auch wenn keine Veränderung erfolgte).
Jemand eine Idee, warum EBX den selben Wert wie EDX enthielt (2. Parameter)? (nur aus meiner Neuier herraus :wink: )

Apollonius 30. Mai 2008 19:09

Re: Byte an bestimmter Speicherposition mit Assembler lösche
 
Schau doch einfach mal in der CPU-Ansicht nach.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:54 Uhr.
Seite 1 von 3  1 23      

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 by Thomas Breitkreuz