Assembler: Frage zu verschiebbaren Programmen


Assembler: Frage zu verschiebbaren Programmen

von mp-one » So 23. Nov 2008, 12:23
Hallo Assembler-Kenner,

ich habe mit dem ATMAS II ein paar kleinere Assembler-Routinen (Invertieren einer Zeile, ATASC-to-Int, etc.) erstellt, die ich per X=USR(...) von BASIC aus aufrufe. Da ich möglichst von absoluten Adressen (Page 6) unabhängig sein will, habe ich nur relative Sprünge verwendet, also z.B. BCC und BEQ statt JSR und JMP. Dazu habe ich noch ein BASIC-Tool geschrieben, welches die Objektprogramme in einen String wandelt. Das klappt bisher sehr gut.

Meine Frage wäre nun, welche weiteren Tipps und Kniffe es gibt, um Programme adressunabhängig zu halten. Zum Beispiel bei einer Wertetabelle, die ich im ATMAS mit DFB b1,b2,..,bn definiere und dann indiziert einzelne Werte von dort abrufen möchte. Gibt es da Möglichkeiten oder geht das nur mit absoluten Adressen?

Gruß,

Michael

von Bernd » So 23. Nov 2008, 13:06
Hallo Michael,

ist bei mir zwar schon sehr lange her aber könnte es nicht so gehen:
Die Daten legst du am Ende des Strings mit dem Assemblerbefehlen ab.
Nach dem Starten des Assemblerprogrammes sollte der Stackpointer ausgelesen
und mit dem Offset also der Differenz zwischen der momentanen Position und den Daten berechnet werden.

Ich hoffe ich bin verständlich gewesen,
Bernd

von mp-one » So 23. Nov 2008, 13:16
Bernd hat geschrieben:Hallo Michael,

ist bei mir zwar schon sehr lange her aber könnte es nicht so gehen:
Die Daten legst du am Ende des Strings mit dem Assemblerbefehlen ab.
Nach dem Starten des Assemblerprogrammes sollte der Stackpointer ausgelesen
und mit dem Offset also der Differenz zwischen der momentanen Position und den Daten berechnet werden.

Ich hoffe ich bin verständlich gewesen,
Bernd


Hallo Bernd,

danke, der Tipp ist gut. An sowas in der Art hatte ich auch schon gedacht, es aber noch nicht probiert bzw. noch nicht das Know How, es zu programmieren.

[Edit:] Auf den Stackpointer kann man ja mit "TSX" über das X-Reg. zugreifen, wie ich gerade nachgelesen habe. Ist bei mir auch alles schon länger her.

[Edit:] Eine Idee, die ich noch hatte, wäre, die Adresse des Strings noch mal per USR zu übergeben, da hätte man dann auch die Startadresse des ML-Programms.


Gruß,

Michael

von Dietrich » Di 25. Nov 2008, 23:55
Hallo Michael,

mit dem Stackpointer kommst Du zwar an die Returnadresse des USR-Befehls heran, die interessiert Dich aber gar nicht, da Du ja die Startadresse Deines USR-Progs haben willst. Ich habe soeben das BASIC-ROM nach JMP ($xxxx) gescannt und einen JMP ($00D4) gefunden. D.h die Anfangsadresse Deines USR-Programms solltest Du in $D4/$D5 finden. Damit kannst Du durch Addieren des Abstands vom Codebeginn bis zum Datenbeginn (kann Dir der Assembler ausrechnen) leicht die absolute Adresse Deiner Daten berechnen; etwa so:

Code: Alles auswählen
tmp   .eq $30  ; $30-$35 werden nur temporär vom SIO benutzt

code pla   ; Anzahl der Argumente holen
cld        ; zur Vorsicht (wir sind ja im BASIC, das mit BCD rechnet)
clc
lda $d4
adc #daten-code
sta tmp
lda $d5
adc /daten-code
sta tmp+1

ldy #irgendwas
lda (tmp),y    ; Zugriff auf die Daten
...
rts
daten  .da #1, #2,#3  ; die Daten

Gruß Dietrich (der früher auch 6502-Code in Strings versteckt hat)

von mp-one » Do 27. Nov 2008, 16:21
Hallo Dietrich,

Dietrich hat geschrieben:mit dem Stackpointer kommst Du zwar an die Returnadresse des USR-Befehls heran, die interessiert Dich aber gar nicht...


da hast Du recht. Ich hatte zuerst gedacht, die Startadresse des ML-Programms liegt auch auf dem Stack, dem ist aber wohl nicht so. Nur die BASIC-Rücksprungadresse und die Parameter liegen dort. Daher meine Idee, die Adresse des ML-Strings nochmals zu übergeben, etwa so: X=USR(ADR(ML$), ADR(ML$), param1, param2, ...) und dann wie einen normalen Parameter vom Stack zu holen. Natürlich nicht gerade elegant...

... Ich habe soeben das BASIC-ROM nach JMP ($xxxx) gescannt und einen JMP ($00D4) gefunden. D.h die Anfangsadresse Deines USR-Programms solltest Du in $D4/$D5 finden.


Klasse, das werde ich mal ausprobieren. $D4,$D5 sind ja auch die Adressen, wo das Ergebnis (Low,High) der ML-Routine abgelegt werden kann. Dieses wird ja dann in der Variablen X zurückgegeben. Wenn das mit $D4,$D5 dann noch unter Turbo BASIC funktioniert, wäre das eine Top-Lösung :D !!

Gruß und danke,

Michael

von mp-one » Do 27. Nov 2008, 16:53
Zu obigem habe ich eben auch folgendes gefunden:

http://oort.com/turbots/asm.htm

When BASIC passes control to your code, it stores the runtime starting address at $D4 and $D5 in the usual low-byte, high-byte format. You can use $D4 as RELSTART. If your program calls the floating point package, the contents of $D4 and $D5 will be destroyed.


...man muss nur wissen, wonach man suchen muss. Diesmal hat google: "atari basic $d4 $d5" das Ergebnis gebracht. Freilich musste man dazu die Lösung des Problems eigentlich schon kennen :roll: .

Gruß,

Michael

von mp-one » Fr 28. Nov 2008, 11:33
Hallo,

ich habe es nun auch mal selbst probiert. Die Startadresse eines mit X=USR(ADR(ML$),...) aufgerufenen ML-Programms findet sich in ATARI BASIC und auch in Turbo BASIC in $D4, $D5. Weiteren Experimenten steht nun nichts mehr im Wege :D !

Gruß,

Michael

von mp-one » Fr 28. Nov 2008, 17:59
Hi Dietrich,

Code: Alles auswählen
adc #daten-code
adc /daten-code


# = LSB und / = MSB, ne?

SynAssembler, nehme ich an.


Gruß,

Michael

von Dietrich » Sa 29. Nov 2008, 02:10
So ist es - der SynAssembler ist immer noch mein Lieblingsassembler auf dem ATARI :)