![]() |
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:
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.
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; |
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?
|
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. |
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:
Dabei scheint es erstaunlicherweiße egal zu sein, ob ich EBX oder EDX nehme, funktioniert beides, was mich etwas verwirrt.
procedure ByteLoeschen2(p: Pointer; Index: Byte); assembler;
asm mov Byte [EAX + EBX], 0 end; Man sollte aber normalerweiße das 'D'-Register für das 2te Argument nehmen? Was genau ist mit 'prt' eax gemeint? |
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. |
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. |
Re: Byte an bestimmter Speicherposition mit Assembler lösche
Hier mal der Quelltext der ganzen Unit:
Delphi-Quellcode:
Wenn dadurch klar wird, warum der zweite Parameter auch in EBX liegt, lasst es mich wissen.
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. |
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 |
Re: Byte an bestimmter Speicherposition mit Assembler lösche
Delphi-Quellcode:
Funktionen sind nun so verändert, dass sie EBX nicht mehr verwenden (auch wenn keine Veränderung erfolgte).
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; Jemand eine Idee, warum EBX den selben Wert wie EDX enthielt (2. Parameter)? (nur aus meiner Neuier herraus :wink: ) |
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. |
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