Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi -> Assembler -> Interrupt (https://www.delphipraxis.net/193280-delphi-assembler-interrupt.html)

juelin 11. Jul 2017 18:48

Delphi -> Assembler -> Interrupt
 
hi Leute,
bin dabei Assembler in Delphi zu lernen.
Habe ein kleines einfaches Programm gemacht, welches die Maus abfragt.
Nur bei Interrupt bekomme ich eine Fehlermeldung:

procedure TForm1.Maus_an;
asm
mov ax, 01h
int 33h
end;

Im Projekt ist eine Exception der Klasse $C0000005 mit der Meldung
'Zugriffsverletzung bei 0x005b4b64; Lesen von Adresse 0xffffffff aufgetreten'

Habe Windows 7 und XE5

Abgesicherter Modus habe ich schon probiert, bringt nix.

Hat jemand da Ahnung?

Gruß Jürgen

himitsu 11. Jul 2017 19:29

AW: Delphi -> Assembler -> Interrupt
 
Ganz einfache Lösung.

Rate mal, was der Fehlercode $C0000005 bedeutet.

$C0000005 ($00000005)
STATUS_ACCESS_VIOLATION (ERROR_ACCESS_DENIED)
Access is denied


Diese Interupts gibt es im WinNT nicht mehr, für User-Mode-Programme.
Damals, als noch DOS, Win31 oder Win9x ... aber ist schon lange her.

juelin 11. Jul 2017 19:43

AW: Delphi -> Assembler -> Interrupt
 
Danke für die Antwort.
Aber wie macht man das in Assembler jetzt?
Gruß Jürgen

himitsu 11. Jul 2017 19:46

AW: Delphi -> Assembler -> Interrupt
 
Zitat:

Zitat von juelin (Beitrag 1376491)
Aber wie macht man das in Assembler jetzt?

In deinem Fall (Beispielcode): Garnicht.

Man ruft die entsprechende WinAPI auf (CALL),
aber das kann man auch gleich direkt im Pascal machen.

MSDN-Library durchsuchenGetCursorPos

juelin 11. Jul 2017 19:50

AW: Delphi -> Assembler -> Interrupt
 
danke,
wird wohl nix mit Assembler in Delphi.
Gruß Jürgen

HolgerX 12. Jul 2017 04:25

AW: Delphi -> Assembler -> Interrupt
 
Hmm..

Zitat:

Zitat von juelin (Beitrag 1376493)
danke,
wird wohl nix mit Assembler in Delphi.
Gruß Jürgen

Das hat nichts mit Delphi zu tun!

Die Zugriffsbeschränkung kommt vom Betriebssystem, hier somit von Windows..
Egal welchen Compiler Du hier nimmst, es wird auch damit diesen Fehlercode geben.

Wenn Du also unbedingt direkt mit Interrupts arbeiten möchtest, dann musst Du dir ein anderes Betriebssystem nehmen, wo der direkte Zugriff gestattet ist.

jaenicke 12. Jul 2017 09:01

AW: Delphi -> Assembler -> Interrupt
 
Zitat:

Zitat von juelin (Beitrag 1376493)
wird wohl nix mit Assembler in Delphi.

Du kannst mit Assembler in Delphi ja mehr machen als Hardware direkt ansteuern...
Du kannst dir ja Beispiele aus diesem Jahrtausend suchen. ;-)

Du kannst z.B. auch einfach mal kleine Funktionen schreiben, einen Haltepunkt setzen und wenn du dort ankommst einfach mal ins CPU-Fenster schauen wie dazu der Assemblercode aussieht. (Strg + Alt + C oder Ansicht --> Debug-Fenster --> CPU-Fenster --> CPU)

mael 12. Jul 2017 17:45

AW: Delphi -> Assembler -> Interrupt
 
Zitat:

Zitat von juelin (Beitrag 1376485)
procedure TForm1.Maus_an;
asm
mov ax, 01h
int 33h
end;

Bei Assembler denkt man immer man wäre näher an der Hardware, aber der Interrupt ist auch nur ein Funktionsaufruf der unter DOS an den Maustreiber weitergleitet wird.

Siehe z.B. hier: http://stanislavs.org/helppc/int_33-0.html
Zitat:

on return:
AX = 0000 mouse driver not installed
FFFF mouse driver installed
Unter DOS wurden Systemfunktionen durch Interrupts aufgerufen, weil es die einzige Möglichkeit ist bei singlethreaded Anwendungen die Kontrolle abzugeben. Unter Win3.1 wurde dafür kooperatives Multitasking verwendet. Man muss hier regelmäßig prüfen ob es neue Fensterbotschaften gibt und diese verarbeiten oder Yield aufrufen um dem Betriebssystem zeitweilig die Kontrolle zurückzugeben.

Unter Windows erreicht man Effizienz durch Verwendung von DirectX oder OpenGL oder ähnliche APIs oder spezielle Sound-APIs die niedrige Latenz ermöglichen, wie ASIO oder WASAPI, etc.

Assembler ist nicht an sich schneller oder näher an der Hardware. Compiler erzeugen auch Maschinencode, nur manchmal ist er suboptimal. Wenn es darum geht eine API-Funktion oder Interrupt aufzurufen ist es eher unwahrscheinlich dass beim Aufruf groß Latenz dazukommt.

Allerdings kannst du Windows-APIs (oder andere C-APIs wie sie heute üblich sind) auch per Assembler aufrufen. Dafür musst du nur die Calling-Convention kennen.

Ich habe hier mal ein einfaches Beispiel für GetCursorPos gemacht:
Code:
procedure Success;
begin
  ShowMessage('Success');
end;

procedure Fail;
begin
  ShowMessage('Fail');
end;

procedure DoSomethingInAssembler;
var
  p: TPoint;
asm
  // load address of p in eax and push it onto the stack
  lea eax, [p]
  push eax

  // GetCursorPos expects its TPoint parameter to be on the stack (stdcall convention)
  call GetCursorPos
  // boolean result returned in eax
  cmp eax,0

  // jump to fail if eax=0
  je @@fail

  // show message 'success' if eax=1
  call Success
  jmp @@exit

@@fail:
  call Fail

@@exit:
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  DoSomethingInAssembler;
end;
Wenn man statt "lea eax, [p]" "mov eax, 0" schreibt, wird er "Fail" ausgeben, weil man nun einen Null-Pointer übergeben hat. Der Code funktioniert nur für 32-Bit Windows, die calling convention unter Win64 ist anders.

Das nur als kleines Beispiel. Falls noch nicht bekannt, Strg+Alt+C zeigt das CPU-Fenster (während dem Debuggen), wo man die Assembler-Instruktionen sehen kann, die dem Pascal-Code entsprechen.

Assembler ist wirklich nur selten sinnvoll heutzutage, um den Compiler zu überzeugen einige umständliche Konstrukte zu vermeiden, oder ungewöhnliche calling conventions zu unterstützen oder sonstige Hacks. In seltenen Fällen um SIMD-Instruktionen zu verwenden, falls der Compiler sie nicht unterstützt. Aber auch da gibt es normalerweise bessere Lösungen wie z.B. OpenCL.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:23 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