Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Inline Asm Problem (https://www.delphipraxis.net/148776-inline-asm-problem.html)

JnZn558 8. Mär 2010 01:52


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.

Medium 8. Mär 2010 04:44

Re: Inline Asm Problem
 
Willste dir damit ne Medallie für die beste Fehlerbeschreibung 2010 verdienen?

hoika 8. Mär 2010 05:43

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

himitsu 8. Mär 2010 08:27

Re: Inline Asm Problem
 
Delphi-Quellcode:
@str: db 'Hello World', $0
- ergibt einen AnsiText also PAnsiChar
- 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:

Neutral General 8. Mär 2010 08:34

Re: Inline Asm Problem
 
Ich denke mal das größte Problem ist, dass die Zeile

Delphi-Quellcode:
@str: db 'Hello World', $0
Vom Prozessor als Code ausgeführt wird. Und was für ein AssemblerCode sich hinter 'Hello World' versteckt weiß erstmal niemand ;-)

JnZn558 8. Mär 2010 15:07

Re: Inline Asm Problem
 
Zitat:

Zitat von Neutral General
Ich denke mal das größte Problem ist, dass die Zeile

Delphi-Quellcode:
@str: db 'Hello World', $0
Vom Prozessor als Code ausgeführt wird. Und was für ein AssemblerCode sich hinter 'Hello World' versteckt weiß erstmal niemand ;-)

ich hatte auch mal gedacht, das problem tritt vl bei unicode auf, also hatte ich auch so geaendert

Delphi-Quellcode:
@str: dw 'Hello World', $0
aber leider weigert der compiler hier die arbeit

himitsu 8. Mär 2010 15:14

Re: Inline Asm Problem
 
Zitat:

Zitat von JnZn558
Delphi-Quellcode:
@str: dw 'Hello World', $0
aber leider weigert der compiler hier die arbeit

Tja, dann mag halt DW diese Parameter einfach nicht?
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.

Namenloser 8. Mär 2010 15:15

Re: Inline Asm Problem
 
Falls es daran liegt, hast du mal probiert, die entsprechende Stelle einfach mithilfe eines JMP-Befehls zu überspringen?
Delphi-Quellcode:
push edx
jmp @code
@str: db 'Hello World', $0
@code:
lea edx, @str
mov TAsm[eax].m_strAsm, edx
pop edx
Ansonsten würde es sicherlich helfen, einen Breakpoint zu setzen und im CPU-Fenster mit F7 durchzusteppen.

gammatester 8. Mär 2010 15:16

Re: Inline Asm Problem
 
Zitat:

Zitat von JnZn558
Zitat:

Zitat von Neutral General
Ich denke mal das größte Problem ist, dass die Zeile

Delphi-Quellcode:
@str: db 'Hello World', $0
Vom Prozessor als Code ausgeführt wird. Und was für ein AssemblerCode sich hinter 'Hello World' versteckt weiß erstmal niemand ;-)

ich hatte auch mal gedacht, das problem tritt vl bei unicode auf, also hatte ich auch so geaendert

Delphi-Quellcode:
@str: dw 'Hello World', $0
aber leider weigert der compiler hier die arbeit

Damit ist gemeint, daß die CPU die Bytes des Strings als OPCodes interpretiert. Die Mindestforderung für Nichtabsturz ist, daß Du einen Sprung über den String machst:
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;

JnZn558 8. Mär 2010 16:18

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:

Project Project.exe raised exception class EInOutError with message 'I/O error 105'.

Blup 8. Mär 2010 16:39

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.

DeddyH 8. Mär 2010 16:42

Re: Inline Asm Problem
 
Abgesehen davon wird Test überhaupt nicht instanziert.

guinnes 8. Mär 2010 17:13

Re: Inline Asm Problem
 
Dazu wird dein Functionsergebnis nicht ( wie sonst üblich ) in EAX zurückgegeben

gammatester 8. Mär 2010 17:16

Re: Inline Asm Problem
 
Zitat:

Zitat von JnZn558
Zitat:

Project Project.exe raised exception class EInOutError with message 'I/O error 105'.

{$apptype console} fehlt für writeln!

JnZn558 8. Mär 2010 20:50

Re: Inline Asm Problem
 
Zitat:

Zitat von gammatester
Zitat:

Zitat von JnZn558
Zitat:

Project Project.exe raised exception class EInOutError with message 'I/O error 105'.

{$apptype console} fehlt für writeln!

jo, das is es, was zum absturz macht, danke

Zitat:

Zitat von DeddyH
Abgesehen davon wird Test überhaupt nicht instanziert.

achja, Delphi, vergiss ich fast immer, komme von C++, so es is kein absturz mehr da, aber es zeigt auch nichts an.

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.

himitsu 8. Mär 2010 21:20

Re: Inline Asm Problem
 
Zitat:

Zitat von JnZn558
aber es zeigt auch nichts an.

Dir wurde schon mehrmals gesagt, daß ein String eine komplexere interne Struktur besitzt ... das kann so einfach nichts werden.

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;

JnZn558 8. Mär 2010 21:35

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.

JnZn558 8. Mär 2010 21:40

Re: Inline Asm Problem
 
Zitat:

Zitat von himitsu
Zitat:

Zitat von JnZn558
aber es zeigt auch nichts an.

Dir wurde schon mehrmals gesagt, daß ein String eine komplexere interne Struktur besitzt ... das kann so einfach nichts werden.

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;

danke sehr, dieser code gefaellt mir sehr gut. vielen dank fuer die muehe und hilfen an alle beteiligten

Namenloser 8. Mär 2010 21:50

Re: Inline Asm Problem
 
Darf man fragen, wozu das ganze?
Delphi-Quellcode:
function ShowText: PWideChar;
const
  str: WideString = 'Hello World!';
begin
  Result := PWideChar(str);
end;
Das sollte doch genau so funktionieren und ist deutlich lesbarer.

guinnes 9. Mär 2010 07:36

Re: Inline Asm Problem
 
Zitat:

Zitat von NamenLozer
Das sollte doch genau so funktionieren und ist deutlich lesbarer.

Und schneller

Neutral General 9. Mär 2010 09:52

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.

JnZn558 10. Mär 2010 15:33

Re: Inline Asm Problem
 
Zitat:

Zitat von guinnes
Zitat:

Zitat von NamenLozer
Das sollte doch genau so funktionieren und ist deutlich lesbarer.

Und schneller

meinste du schneller coden, oder die ausfuehrzeit

Zitat:

Zitat von Neutral General
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.

jojo, nur aus lernzweck

himitsu 10. Mär 2010 16:17

Re: Inline Asm Problem
 
Zitat:

Zitat von JnZn558
meinste du schneller coden, oder die ausfuehrzeit

Beides ... der Compiler optimiert manchmal besser, als man denkt.

guinnes 10. Mär 2010 19:19

Re: Inline Asm Problem
 
Zitat:

Zitat von JnZn558
meinste du schneller coden, oder die ausfuehrzeit

Ich kann himitzu nur zustimmen. Die Version mit dem JMP über den String ist mit Sicherheit zur Ausführungszeit ganz deutlich langsamer als PurePascal und braucht dazu deutlich länger zum schreiben. Wenn man sich manche Konstukte im Assembler ankuckt, optimiert der Kompiler schon verdammt gut ( ich sag da nur Case )

himitsu 10. Mär 2010 21:05

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 12:20 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