Wie beendet man ein Maschinenprogramm richtig?

Moderator: Rockford

Antworten
Benutzeravatar
Olix
Beiträge: 990
Registriert: 17.08.2021 07:06
Has thanked: 117 times
Been thanked: 407 times
Kontaktdaten:

Wie beendet man ein Maschinenprogramm richtig?

Beitrag von Olix »

Und schon wieder ich mit einer nervigen Anfängerfrage:

Nachdem ich jetzt meine ersten kleinen Assemblerprogramme zum laufen bekommen habe eine komische Frage:

Wie beende ich denn im besten Fall ein Maschinenspracheprogramm.
Ich dachte mir, so dass es auf jeden Fall am Ende wieder in das DOS springt.

Gibt es dazu eine feste Sprungadresse?

Ich habe es bisher einfach mit einem BRK beendet.
Das scheint ja auch zu funktionieren, kommt mir aber nicht sehr sauber vor....

Benutzeravatar
Dr. Irata
Beiträge: 937
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 268 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von Dr. Irata »

… spring doch einfach durch den Vektor für den Warmstart 😉

Benutzeravatar
Dr. Irata
Beiträge: 937
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 268 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von Dr. Irata »

... ich muss ehrlich sagen, daß mein Programm gar keine Option hat wieder ins DOS zurückzuspringen...
Mein Programm startet als AUTORUN auf einer .atr Disk, wo ein Mini-Dos drauf ist.
Ich denke, um es zu beenden sollte ein RTS reichen.
Ansonsten kann man natürlich durch den Wramstart -/ oder Kaltstartvektor springen ... bzw. eigentlich auch direkt ins DOS zurückspringen.
Entsprechende Adressen und Vektoren finden sich bei Speicherstelle 9 bzw. der Warmstartvektor ist bei 10,11 oder bei 580 ($244) = Kaltstart-Flag und entsprechen die Stellen 578/579 = ($242,$243) Adresse für den Disk-Boot-Loader.

FlorianD
Beiträge: 182
Registriert: 19.08.2021 00:18
Has thanked: 21 times
Been thanked: 55 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von FlorianD »

DOS ruft INIT und START per JSR auf.

Benutzeravatar
Olix
Beiträge: 990
Registriert: 17.08.2021 07:06
Has thanked: 117 times
Been thanked: 407 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von Olix »

Vielen Dank für die vielen unterschiedlichen Tips.

Ich werde sie alle ausprobieren.
Mal sehen für welche Lösung ich mich dann entscheide.

Erhard
Beiträge: 558
Registriert: 04.11.2021 15:52
Has thanked: 52 times
Been thanked: 111 times
Kontaktdaten:

Wie beendet man ein Maschinenprogramm richtig?

Beitrag von Erhard »

Hi Olix,

es ist nicht richtig, ein Maschinenprogramm über BRK zu beenden. BRK springt nicht zurück sondern hört an der Stelle einfach auf und löst einen Softwareinterrupt aus.

RTS ist grundsätzlich richtig. Eigentlich finde ich, daß der Befehl RFS heißen müßte, denn es soll ja "Return From Subroutine" heißen. Aber man könnte es ja "Return To Subroutine-Call" nennen :-)

Wenn Du also vom DOS aus folgendes Programm aufrufst:

LDA #$01
TAX
INX
TXA
RTS

kommst Du an die Stelle zurück, wo Du herkommst. Bei einem CLI-DOS sicherlich die Eingabezeile.

Wenn das Programm so aussieht:

LDA #$01
TAX
INX
TXA
JMP (DOSINI)

kommst Du auch ins DOS zurück. Ich müßte jetzt ausprobieren, ob bei einem DOS mit Menü dadurch das Menü neu geladen wird, weiß ich halt gerade nicht.

Was ich auch überperprüfen müßte wäre ob der Prozessorstapel bei diesem Rücksprung (der eigentlich keiner ist) aufgeräumt ist. Es könnte nämlich sein, daß Du zwar wieder im DOS landest, aber da Du nicht zurückgesprungen bist könnte die Rücksprungadresse noch auf dem Prozessorstapel liegen. Dann würde der Stapel mit jedem Programmaufruf um 2 Byte wachsen bis er überläuft. Es kann aber auch sein, daß die INI-Routine des DOS den Stapel zurücksetzt. Dann wäre das immer noch ein Fehler, aber ohne Auswirkung.

Ferner könntest Du auf die Idee kommen, daß es nicht gut ist, wenn Durch Dein Programm die Werte von A, X und Y verändert werden. Das DOS muß ja damit klar kommen, daß da plötzlich was anderes drin steht (ich hatte noch keinen Fall, wo es das nicht tut, soll nur als Beispiel dienen). Man könnte die Werte retten, wie man das bei einem Interrupt machen muß. Dann sieht das so aus:

PHA ;retten
TXA
PHA
TYA
PHA
LDA #$01 ;programm
TAX
INX
TXA
PLA ;wiederherstellen
TAY
PLA
TAX
PLA
RTS

Wenn Du da mit PHA nicht genauso viel auf den Stapel schiebst wie Du mit PLA wieder herunter nimmst dann knallt es beim RTS richtig.

BRK nimmt übrigens die Rücksprungadresse nicht vom Stapel.

Empfohlenes Buch: SYBEX: Programmierung des 6502 (Rodnay Zaks)

CU, Erhard

Benutzeravatar
pps
Beiträge: 530
Registriert: 18.06.2021 23:05
Has thanked: 115 times
Been thanked: 206 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von pps »

Sollte das Programm eigene DLI oder VBI nutzen, ist auch daran zu denken vor dem Ende des Programms die alten Einstellungen wieder herzustellen.

Daher ist ein JMP $E474 oder $E477 die einfachere Variante um das Programm zu beenden. Da macht das System einen Reset und Du musst nicht darauf achten, was vorher war.
PP´s of STARSOFTBerlin__________github|meine Webseite|Demozoo

Benutzeravatar
Olix
Beiträge: 990
Registriert: 17.08.2021 07:06
Has thanked: 117 times
Been thanked: 407 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von Olix »

... nochmals vielen Dank für die vielen Tipps.

Dass BRK die unsauberste Lösung ist war mir ja klar. Kam nur daher, dass dies so in den Beispielen des ATMAS-II Manuals und im Assemblerbuch von Peter Finzel immer so gemacht wurde.
Inzwischen weiß ich, dass bei einem BRK ein Interrupt ausgelöst wird, der den Interrupt-Hanlder über die feste Adresse fffe/ffff aufruft. Der Interrupt-Handler erkennt am gesetzten B-Flag, dass der Interrupt von einem BRK stammt und verzweigt per indirektem Sprung über den Vektor "VBREAK - $206,$207). Dieser wiederum wird vom ATMAS-Assembler so gestzt, dass ein Programm aufgerufen wird, welches den Inhalt der Prozessorregister am Bildschirm ausgibt.

Schön und verständlich ist dies beschrieben in "Das Assemblerbuch von Peter Finzel" Abschnitt 11.2 - Seite 96

Ich habe mich jetzt dazu entschieden, mein Programm per RTS zu beenden und das funktioniert auch gut. Solange man das Programm nicht unter DOS per "<M> Run at Adrtess" startet, denn hier scheint DOS 2.5 nicht per JSR sondern per JMP zu springen.

Olix

P.S. Was mich ja beruhigt ist, dass es sich, bei den vielen unterschiedlichen Ansätzen die hier vorgeschlagen wurden, gar nicht um eine soooooo triviale Frage handelt. ;)

Benutzeravatar
atarixle
Beiträge: 271
Registriert: 18.06.2021 21:19
Has thanked: 29 times
Been thanked: 51 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von atarixle »

Erhard hat geschrieben:
20.06.2022 11:58
RTS ist grundsätzlich richtig. Eigentlich finde ich, daß der Befehl RFS heißen müßte, denn es soll ja "Return From Subroutine" heißen. Aber man könnte es ja "Return To Subroutine-Call" nennen :-)
Falls ich mich recht erinnere, heißt der Befehl laut "Der Atari-Assembler" tatsächlich "ReTurn from Subroutine". Das 'T' in der Mitte steht für das in "Return".

Benutzeravatar
atarixle
Beiträge: 271
Registriert: 18.06.2021 21:19
Has thanked: 29 times
Been thanked: 51 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von atarixle »

Olix hat geschrieben:
20.06.2022 13:15

P.S. Was mich ja beruhigt ist, dass es sich, bei den vielen unterschiedlichen Ansätzen die hier vorgeschlagen wurden, gar nicht um eine soooooo triviale Frage handelt. ;)
Sie ist in der Tat nicht trivial. Meist ist die Standard-Methode ein Programm zu beenden, den Rechner aus- und wieder einzuschalten. Viele Spiele überschreiben das DOS, un mehr Speicher nutzen zu können, dann ist nichts mehr da, wohin sie zurückspringen könnten.
Und deshalb ist das korrekte Verlassen eines Programms ein sehr wenig besprochenes Thema.

Benutzeravatar
Dr. Irata
Beiträge: 937
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 268 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von Dr. Irata »

Das war auch für mich schon einer der Gründe, warum ich an meinen Atari 400 (48kB) einen kleinen Kaltstart-Taster angebaut habe.
Damit konnte ich jedes Programm ganz einfach mit einem Tastendruck beenden bzw. neu starten, ohne den Rechner ständig aus-/anzuschalten.

Erhard
Beiträge: 558
Registriert: 04.11.2021 15:52
Has thanked: 52 times
Been thanked: 111 times
Kontaktdaten:

Wie beendet man ein Maschinenprogramm richtig?

Beitrag von Erhard »

Hi,

atarixle hat geschrieben:
22.06.2022 10:36
Viele Spiele überschreiben das DOS, un mehr Speicher nutzen zu können, dann ist nichts mehr da, wohin sie zurückspringen könnten.
wie viele Spiele haben ein Menü, über das man sie verlassen könnte? Und wie viele Spiele schafft man durch "bis zum Ende spielen" an den Punkt zu bringen, wo ein Verlassen sinnvoll wäre?

Dieses "Zurückkehren zu einem übergeordneten Programm" ist vermutlich eher bei bestimmten Softwarearten sinnvoll: Hilfsprogramme für ein DOS, Anwenderprogramme wie ein Editor oder Malprogramm, Programmierumgebungen wie ein BASIC(-Modul), Diagnosesoftware wie ein Debugger usw.

CU, Erhard

Benutzeravatar
pps
Beiträge: 530
Registriert: 18.06.2021 23:05
Has thanked: 115 times
Been thanked: 206 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von pps »

Erhard hat geschrieben:
23.06.2022 08:04
...
Dieses "Zurückkehren zu einem übergeordneten Programm" ist vermutlich eher bei bestimmten Softwarearten sinnvoll: Hilfsprogramme für ein DOS, Anwenderprogramme wie ein Editor oder Malprogramm, Programmierumgebungen wie ein BASIC(-Modul), Diagnosesoftware wie ein Debugger usw.
... ABBUC Magazin Intros ;)

Hier am einfachsten immer mit jmp $E474 über den warm reset gehen. Das ABBUC Magazin Programm wurde so geschrieben, dass es dadurch wieder gestartet wird ohne es neu laden zu müssen.
PP´s of STARSOFTBerlin__________github|meine Webseite|Demozoo

Online
Benutzeravatar
CharlieChaplin
Beiträge: 586
Registriert: 18.06.2021 22:59
Has thanked: 115 times
Been thanked: 153 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von CharlieChaplin »

Wie beendet man ein Maschinenprogramm richtig?

Mit Elvis: Return to sender (RTS). :lol:
Habe ich mir als nicht-Programmierer so gemerkt. :D

Benutzeravatar
LarsImNetz
Beiträge: 152
Registriert: 24.08.2021 18:27
Has thanked: 109 times
Been thanked: 81 times
Kontaktdaten:

Re: Wie beendet man ein Maschinenprogramm richtig?

Beitrag von LarsImNetz »

Hi,

ich verwende meist auch nur RTS fürs Beenden. Früher(tm) fand ich es witzig die Programme resetfest zu machen. So musste man den Rechner hart ausschalten, um ins DOS zurück zu kehren. Heute find ich es aber eher suboptimal gerade auch um die Hardware etwas mehr zu schonen verzichte ich auf solche Dinge. Dann eher JMP $E474 für einen Warmreset nutzen.
Register auf den Stack zu sichern für DOS ist unnötig.
Eher merkt man sich den Stackpointer per TSX und stellt diesen am Ende wieder her, per TXS dann RTS und man ist fein raus, egal wie man im Stack gepfuscht hat, einzige Voraussetzung man hat es im Stack nicht übertrieben.

LG
Lars

Antworten

Wer ist online?

Mitglieder in diesem Forum: CharlieChaplin, wosch und 1 Gast