Autor Thema: FAR-CALL mit NASM  (Gelesen 6609 mal)

bscreator

  • Gast
Gespeichert
« am: 15. November 2011, 14:48 »
Hallo,

ich wollt mal wissen, wie man einen FAR-CALL mit NASM machen kann.
Beim Aufruf eines Interrupts, z.B.
mov ah, 0x0E
int 0x10
passiert ja nichts anderes, als ein FAR-CALL, der CS:IP auf dem Stack speichert und einen Sprung zur Interruptroutine macht.

Mit dem Emulator Emu8086 kann man dasselbe mithilfe der Zeilen
mov ah, 0x0E
call dword ptr es:[0x10*4]
erreichen.

Die obige Zeile (call dword...) kann man mit NASM nicht assemblieren.
Hab es mit call dword far [es:word 0x10*4] versucht. Assemblieren geht zwar, aber es wird kein Zeichen ausgegeben.

Wo liegt der Fehler ?

Danke,
bsc

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 15. November 2011, 15:37 »
es ist kein Codesegment. Wenn du das Segment als Immediate-Wert hast, müsste das so gehen, ansonsten leg die Daten auf den Stack und mach ein retf.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bscreator

  • Gast
Gespeichert
« Antwort #2 am: 15. November 2011, 16:49 »
Das mit dem CS und IP auf den Stack hat meine Programme immer hunderttausendmal größer gemacht, als sie eigentlich sind. Da meine API außerhalb des Kernelsegments liegt, will ich lediglich meine API-Funktionen aufrufen können, ohne ständig bei jedem API-Aufruf CS sowie IP mittels des $-Operators manuell auf den Stack pushen zu müssen.

Hab das ganze jetzt mal mit
call far [es:0x10*4] gemacht. Allerdings wird dann "HeHello World..." statt "Hello World" ausgegeben.
(Mittels int 0x10 wird der korrekte String "Hello World" ausgegeben.)

Wo liegt der Fehler ?

Danke,
bsc

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 15. November 2011, 18:14 »
Beim Aufruf eines Interrupts, z.B.
mov ah, 0x0E
int 0x10
passiert ja nichts anderes, als ein FAR-CALL, der CS:IP auf dem Stack speichert und einen Sprung zur Interruptroutine macht.
Doch es passiert noch was anderes: Bevor die Rücksprungadresse auf den Stack gelegt wird, werden die Flags auf den Stack gelegt. Weil du das vor deinem call nicht machst, tritt vermutlich der Fehler auf.
Dieser Text wird unter jedem Beitrag angezeigt.

bscreator

  • Gast
Gespeichert
« Antwort #4 am: 15. November 2011, 18:47 »
Du hast recht, Jidder.
Hab zwar gewusst, dass die Flags auch gesichert werden, hab das allerdings für einen nicht notwendigen Faktor angesehen. Mit dem vorherigen pushen der Flags funktioniert das ganze.

Noch ne Frage :
Wenn ich meine eigene API, welche z.B. bei der physikalischen Adresse 0x30000 liegt, anspringen möchte, müsste doch eigentlich bei so einem FAR-CALL die Zeile call far [es:0x0000] ausreichen (wenn man davon ausgeht, dass vorher ES mit dem Wert 0x3000 vorbelegt wurde), oder ?

Vielen Dank,
bsc
 

LittleFox

  • Beiträge: 306
    • Profil anzeigen
    • LF-Net.org
Gespeichert
« Antwort #5 am: 15. November 2011, 18:53 »
Hi,

nur mal eine Frage an dich über die ich die ganze Zeit nachgrübel: gibt es irgendeinen Grund warum du nicht int 0x10 aufrufst?

Zu deiner Frage: ich bin zwar kein Assembler-Profi, aber ich denke schon. Wenn du vorher Flags und Rücksprungadresse gesichert hast.

Grüße,
LittleFox

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 15. November 2011, 19:07 »
Wenn an der Adresse 3000:0000 ein far-Zeiger auf die Funktion steht, dann ja. Flags sichern musst du nicht, wenn deine API mit RETF zurückkehrt (und nicht mit IRET).

Wenn die Funktion an Adresse 3000:0000 steht, musst du call 0x3000:0x0000 nehmen.
Dieser Text wird unter jedem Beitrag angezeigt.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 15. November 2011, 22:00 »
Könnte nützlich sein bezüglich des nasm Syntaxes: http://de.wikibooks.org/wiki/Assembler_%2880x86_Prozessor%29-Programmierung:_Unterprogramme_und_Interrupts#Unterprogramme.

PS: Übrigens passiert beim Aufruf eines Interrupts schon noch ein bisschen was anderes als bei einem far call. Das ist auf jeden Fall keine alternative zu int.

LittleFox

  • Beiträge: 306
    • Profil anzeigen
    • LF-Net.org
Gespeichert
« Antwort #8 am: 15. November 2011, 22:04 »
Zitat
PS: Übrigens passiert beim Aufruf eines Interrupts schon noch ein bisschen was anderes als bei einem far call. Das ist auf jeden Fall keine alternative zu int.
Aber wie im Artikel zu Sysenter/Leave steht, passiert viel zu viel ...
Vielleicht will er ja etwas ähnliches, eigenes schaffen? Aber wie würde da Speicherschutz gehen?

Grüße,
LittleFox

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 15. November 2011, 22:09 »
Real Mode. Nuff said.
Dieser Text wird unter jedem Beitrag angezeigt.

LittleFox

  • Beiträge: 306
    • Profil anzeigen
    • LF-Net.org
Gespeichert
« Antwort #10 am: 15. November 2011, 22:14 »
upps ... sry

bscreator

  • Gast
Gespeichert
« Antwort #11 am: 16. November 2011, 14:32 »
Zitat
PS: Übrigens passiert beim Aufruf eines Interrupts schon noch ein bisschen was anderes als bei einem far call. Das ist auf jeden Fall keine alternative zu int.
Das ist mir schon klar, dass da noch ein paar Dinge mehr passieren

Zitat
Wenn die Funktion an Adresse 3000:0000 steht, musst du call 0x3000:0x0000 nehmen.
Danke Jidder. Habs bereits vorher auch rausgefunden.

Danke an alle,
Damit wär das Thema gelöst
bsc

 

Einloggen