![]() |
Inline Asm Problem
das is mein code, compiliere tut es, nur es kratz ab, und ich weiss net was falsch is. uebrigens hab ich delphi 2009
Delphi-Quellcode:
unit inlineasm;
interface type TAsm = class m_strAsm: string; public constructor Create; property Text: string read m_strAsm; end; implementation constructor TAsm.Create; begin asm push edx @str: db 'Hello World', $0 lea edx, @str mov TAsm[eax].m_strAsm, edx pop edx end; end; end. |
Re: Inline Asm Problem
Willste dir damit ne Medallie für die beste Fehlerbeschreibung 2010 verdienen?
|
Re: Inline Asm Problem
Hallo,
wo genau stürzt er ab ? Ich schätze mal, hier mov TAsm[eax].m_strAsm, edx TAsm.m_strAsm gibt es so nicht. Bei m_strAsm handelt es sich nicht um eine Klassen-Variable. Entweder das TAsm ganz weglassen, oder falls es geht, durch Self ersetzen. Die Zeiten von Assembler sind übrigens (fast) vorbei, Und so mit String zu hantieren. ist eh gefährlich. Du weisst schon, dass ein String ein Zeiger (PChar) ist, der "initialisiert" werden muss (SetLength). Und wenn jetzt einer sagt, dass muss man nicht in Delphi, wir reden hier von Assembler ... Heiko |
Re: Inline Asm Problem
Delphi-Quellcode:
- ergibt einen AnsiText also PAnsiChar
@str: db 'Hello World', $0
- String ist aber seit D2009 ein UnicodeString - ein String hat eine bestimmte intere Struktur, welche viel mehr besitzt, als nur den Teil, welche rpraktischer Weise fast wie ein PChar aussieht. Und diese Struktur hast du nicht mit erstellt, sondern du trägst einfach nur den PChar-Zeiger in den "String" ein - selbst wenn du die Stringstruktur ordnungsgemäß erstellt hättest und der Text auch noch als Unicode vorhanden wäre, gäbe es immernoch ein Speicherleck, da ein eventuell vorher in m_strAsm liegender String nicht freigegeben würde. - in EAX ist an soeiner Stelle nicht immer der Self-Pointer, vorallem nicht, da hierbei davor noch die Klasseninitialisierung durchgeführt wird, so daß TAsm[eax] vermutlich nicht auf Self zeigt. [add] - jupp, das von Neutral General genannte kommt dann auch noch mit dazu Fazit: solange du keine Ahnung hast, was du da überhaupt machst und wie gewisse Datentypen intern arbeiten ... laß die Finger von sowas, dazumal es hierbei garkeinen Grund gibt, sowas via ASM lösen zu wollen. :gruebel: |
Re: Inline Asm Problem
Ich denke mal das größte Problem ist, dass die Zeile
Delphi-Quellcode:
Vom Prozessor als Code ausgeführt wird. Und was für ein AssemblerCode sich hinter 'Hello World' versteckt weiß erstmal niemand ;-)
@str: db 'Hello World', $0
|
Re: Inline Asm Problem
Zitat:
Delphi-Quellcode:
aber leider weigert der compiler hier die arbeit
@str: dw 'Hello World', $0
|
Re: Inline Asm Problem
Zitat:
einfache Lösung: gibt die Buchstaben einzeln an und wandle sie notfalls in "Integer"/Word um. Aber egal, da der Rest des Codes sowieso nicht funktionieren kann. |
Re: Inline Asm Problem
Falls es daran liegt, hast du mal probiert, die entsprechende Stelle einfach mithilfe eines JMP-Befehls zu überspringen?
Delphi-Quellcode:
Ansonsten würde es sicherlich helfen, einen Breakpoint zu setzen und im CPU-Fenster mit F7 durchzusteppen.
push edx
jmp @code @str: db 'Hello World', $0 @code: lea edx, @str mov TAsm[eax].m_strAsm, edx pop edx |
Re: Inline Asm Problem
Zitat:
Delphi-Quellcode:
begin
asm push edx jmp @@skip @str: db 'Hello World', $0 @@skip: lea edx, @str mov TAsm[eax].m_strAsm, edx pop edx end; end; |
Re: Inline Asm Problem
Delphi-Quellcode:
unit inlineasm;
interface type TAsm = class m_strAsm: string; function ShowText: AnsiString; public constructor Create; property Text: AnsiString read ShowText; end; implementation constructor TAsm.Create; begin end; function TAsm.ShowText; begin asm push edx jmp @@skip @str: db 'Hello World', $0 @@skip: lea edx, @str mov TAsm[eax].m_strAsm, edx pop edx end; end; end.
Delphi-Quellcode:
program Project;
uses SysUtils, Dialogs, inlineasm; var Test: TAsm; begin try Writeln('Text: ' + Test.Text); // hier soll der fehler sein, hier stopp debugger, und gibt mit I/O error 105 Readln; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; end. Zitat:
|
Re: Inline Asm Problem
Ist auch kein Wunder, eine Stringvariable ist ein Zeiger auf eine etwas kompliziertere Struktur.
Insbesonder gehören dazu Integer für Größe des reservierten Speicher, Referenzzähler, Länge und die Zeichen selbst. Schreib einfach mal in Delphi was die Funktion machen soll und schau das Ergebnis im CPU-Fenster an. |
Re: Inline Asm Problem
Abgesehen davon wird Test überhaupt nicht instanziert.
|
Re: Inline Asm Problem
Dazu wird dein Functionsergebnis nicht ( wie sonst üblich ) in EAX zurückgegeben
|
Re: Inline Asm Problem
Zitat:
|
Re: Inline Asm Problem
Zitat:
Zitat:
Delphi-Quellcode:
program Project;
{$apptype console} uses SysUtils, Dialogs; function ShowText: string; begin asm jmp @start //str = 'Hello World', 0 // alle zeichen hab ich in ascii umgewandelt // und so word also 16 bit unicode zu erzeugen // dachte ich @str: dw 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0 @start: lea eax, @str end; ShowMessage(Result); end; begin try Writeln('Text: ' + (ShowText)); Readln; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; end. |
Re: Inline Asm Problem
Zitat:
Außerdem ist das EAX nur in Bezug auf das Funktionsende das Result, aber Strings und dynamiache Arrays sind kein Result, sondern werden als Parameter übergeben ... das Ganze ist also eine Prozedur mit einem VAR-Parameter für den String ... ergo, du kannst nicht einfach via EAX so das Result zuweisen, da A) String ... also steckt Result wo anders und B) liegt nach deinem ASM-Block nicht das Funktionsende. Schau dir bitte erstmal genauer an, wie das mit den Funktionsparametern, dem Result, speziell auf Methoden bezogen und vorallem wie das mit dem String genau funktioniert, bevor hier noch mehr "gefährlicher Code entsteht. eine eingache Lösung:
Delphi-Quellcode:
function ShowText: PWideChar;
asm lea eax, @str ret @str: dw 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0 end; |
Re: Inline Asm Problem
ich hab nun endlich geschafft
Delphi-Quellcode:
program Project;
{$apptype console} uses SysUtils, Dialogs; function ShowText: PChar; begin asm jmp @start @str: dw 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0 @start: lea eax, @str mov Result, eax; end; end; begin try Writeln('Text: ' + ShowText); Readln; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; end. |
Re: Inline Asm Problem
Zitat:
|
Re: Inline Asm Problem
Darf man fragen, wozu das ganze?
Delphi-Quellcode:
Das sollte doch genau so funktionieren und ist deutlich lesbarer.
function ShowText: PWideChar;
const str: WideString = 'Hello World!'; begin Result := PWideChar(str); end; |
Re: Inline Asm Problem
Zitat:
|
Re: Inline Asm Problem
Ich gehe mal davon aus, dass er diesen Assemblercode nur aus Lernzwecken schreiben will.
Von daher geht es ihm wahrscheinlich nicht so sehr um Lesbarkeit und Effizienz. |
Re: Inline Asm Problem
Zitat:
Zitat:
|
Re: Inline Asm Problem
Zitat:
|
Re: Inline Asm Problem
Zitat:
|
Re: Inline Asm Problem
Ich hatte sogar schonmal Fälle, wo der Compiler besser optimierte, als ich es hinbekommen hätte
und selbst Andere, welche wesentlich besser mit Assembler umgehen, konnten es nicht (viel) besser machen. Assembler lohnt sich praktisch nur dann, wenn der Delphicompiler an dieser schnelle nur nicht optimal genug arbeitet und wenn es wirklich auf jede Nanosekunde ankommt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:44 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