Pascal "absolute" Deklaration - mit Pointer-Array möglich?

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Pascal "absolute" Deklaration - mit Pointer-Array möglic

Beitrag von zatzen »

Ich glaube, ich muss mir jetzt einfach mal Lektüre besorgen zu dem ganzen Thema.
Es sei denn, das war jetzt alles was ich über Assembler wissen muss...

Was Segment Override betrifft, für FS schreibe ich dann einfach

Code: Alles auswählen

db 64h
mov ax, ds:[si]
woraus dann mov ax, fs:[si] wird?

Was, wenn ich jetzt auch noch EAX verwenden will...

So ganz ist mir das nicht klar, und ich schätze, das wird jetz hier zu
weit führen alles einzeln zu hinterfragen. Daher, wie gesagt, Lektüre...

Das wäre vielleicht meine letzte Bitte, wo ich sowas lesen kann,
ASM86FAQ wird hilfreich sein, aber ich sehe hier im letzten Posting auch,
dass da etwas auch der "Intel-Doku" entstammt.

Egal, hab jetzt endlich mal in ASMFAQ reingeguckt mit DOSferatus tollem
Reader, und habe da auch die Sache mit den Prefixes gefunden.

Danke nochmal an alle!
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Pascal "absolute" Deklaration - mit Pointer-Array möglic

Beitrag von zatzen »

Da gibt's halt nur so Sachen, die ich in ASM86FAQ nicht finde.
Sorry für so viele Fragen...

Für Grafikroutinen beispielsweise habe ich bisher " REP MOVSW " verwendet.
Für MOVSW sind die Register DS:SI und ES:DI default. Da Frage ich mich,
wie man diesen Befehl so umbaut, dass es für bspw. FS und GS funktioniert.
Wenn das überhaupt geht. Sonst muss man es eben "per Hand" machen, also
mit Schleife und MOV.

Und bevor ich mich aus Unwissen verheddere, nur eine Frage, auch etwas
das mir neu war:

Wenn man DS als Register verwenden will für Lesezugriffe, dann kann
man sich scheinbar dessen Spezifierung schenken. D.h. es genügt ein
" MOV ... , [SI] " beispielsweise, ohne die Angabe des Segmentregisters.
Und das scheint auch die richtige Vorgehensweise zu sein, wenn man
durch Präfix ein anderes Segmentregister verwenden will, welches es
erst ab dem 386er gibt.
Beispiel: " DB 64H ; MOV AX, [SI] " wird quasi zu " MOV AX, FS:[SI] " ?
Und wie ich das verstanden habe, kann man bis zu 4 Präfixbytes (in der
richtigen Reihenfolge) vor einen Befehl schreiben, um diesen genauer zu
bestimmen.
mov ax, 13h
int 10h

while vorne_frei do vor;
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Pascal "absolute" Deklaration - mit Pointer-Array möglic

Beitrag von freecrac »

zatzen hat geschrieben:Ich glaube, ich muss mir jetzt einfach mal Lektüre besorgen zu dem ganzen Thema.
Es sei denn, das war jetzt alles was ich über Assembler wissen muss...

Was Segment Override betrifft, für FS schreibe ich dann einfach

Code: Alles auswählen

db 64h
mov ax, ds:[si]
woraus dann mov ax, fs:[si] wird?
Besser wäre wohl:

Code: Alles auswählen

db 64h
mov ax, [si]
Was, wenn ich jetzt auch noch EAX verwenden will...
Für "mov eax, fs:[si]"

Code: Alles auswählen

db 64h ; Segment-Override Prefix
db 66h ; Operand-Size Prefix
mov ax, [si]
64 66 8B 04

...

Hier gibt es einen x86-Online-Assembler:
https://defuse.ca/online-x86-assembler.htm#disassembly
Um damit zu arbeiten sollte man allerdings folgendes beachten:
Es wird dort nicht der 16 Bit-Mode verwendet, sondern der 32 Bit-Mode.

Dadurch ändert sich die defaultmäßige Grösse der Operanden und Adressen.
Das bedeutet im 32 Bit-Mode werden für 16 Bit Operanden und für 16 Bit Adressen die Operand-Size und Address-Size Prefixe im Code verwendet und mit eingefügt und für 32 Bit Operanden und für 32 Bit Adressen weg gelassen.
Also genau andersherum wie im 16 Bit-Mode.

Für ein "mov eax, fs:[si]" im 32 Bit-Mode bekommen wir dort: 64 67 8B 04
Weil im 32 Bit-Mode braucht "EAX" kein Operand-size Prefix, aber "SI" als 16 Bit-Adressregister braucht ein Address-Size Prefix.

Für unseren 16 Bit-Mode müssen wir deswegen für das "EAX" ein Operand-size Prefix(66h) mit einfügen und für das "SI" das
Address-Size Prefix(67h) herausnehmen.
So ganz ist mir das nicht klar, und ich schätze, das wird jetz hier zu
weit führen alles einzeln zu hinterfragen. Daher, wie gesagt, Lektüre...
Das wäre vielleicht meine letzte Bitte, wo ich sowas lesen kann,
ASM86FAQ wird hilfreich sein, aber ich sehe hier im letzten Posting auch,
dass da etwas auch der "Intel-Doku" entstammt.

Egal, hab jetzt endlich mal in ASMFAQ reingeguckt mit DOSferatus tollem
Reader, und habe da auch die Sache mit den Prefixes gefunden.

Danke nochmal an alle!
Als Lektüre habe ich selber nur ein PC-Intern Buch (von Data Becker).
Ich hatte Assembler aber vorher schon auf dem C64er kennen gelernt und danach auf dem PC das erste halbe Jahr nur mit Debug gearbeitet, um die X86-Befehle und die Speicherlandschaft zu erkunden. Erst danach habe ich mich auch mit DOS-Befehlen beschäftigt und dann dauerte es noch eine Weile bis ich mir aus dem Internet von Intel mir deren Dokumente heruntergeladen habe.

Ich meine im Internet findet man alles was man für das Lernen von x86-Assembler benötigt.

Eine grobe Vorstellung von Assembler ist aber sehr hilfreich und Englisch-Kenntnisse sollte man auch schon haben.
Mir kommt es so vor, als wenn ich selber ca. die Hälfte meiner Englisch-Kenntnisse im Internet gelernt habe, in dem ich viele Texte gelesen und auch englischsprachige Filme mir angeschaut habe und dann auch in englischen Newsgroups und Foren mich an Diskussionen beteiligt habe. Mangelnde Sprachkenntnisse waren bei technischen Themen eigentlich nie ein grosses Problem, weil dort sehr viel Rücksicht darauf genommen wird und sich jene Teilnehmer deren Muttersprache englisch ist sich wirklich viel Mühe geben ihren Texte so zu schreiben, so dass es verständlich wird was damit gemeint ist.

Ich meine Assembler gehört für den PC doch am ehesten noch zu DOS, auch wenn mit MASM32 Windows-Anwendungen erstellt werden können. So bin ich auch gerne weiterhin gewillt auch hier im DOS-Forum jede Art von Assembler-Fragen für reine DOS-Anwendungen so lange und ausführlich zu beantworten, wie es gewünscht wird.

Dirk
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Pascal "absolute" Deklaration - mit Pointer-Array möglic

Beitrag von freecrac »

zatzen hat geschrieben:Da gibt's halt nur so Sachen, die ich in ASM86FAQ nicht finde.
Sorry für so viele Fragen...
Kein Problem.
Für Grafikroutinen beispielsweise habe ich bisher " REP MOVSW " verwendet.
Für MOVSW sind die Register DS:SI und ES:DI default. Da Frage ich mich,
wie man diesen Befehl so umbaut, dass es für bspw. FS und GS funktioniert.
Wenn das überhaupt geht. Sonst muss man es eben "per Hand" machen, also
mit Schleife und MOV.
Falls ich mich nicht täusche, dann kann man für MOVSB/MOVSW/MOVSD kein Segment-overide Prefix verwenden, aber für lodsb/lodsw/lodsd und für stosb/stosw/stosd.
Und bevor ich mich aus Unwissen verheddere, nur eine Frage, auch etwas
das mir neu war:

Wenn man DS als Register verwenden will für Lesezugriffe, dann kann
man sich scheinbar dessen Spezifierung schenken. D.h. es genügt ein
" MOV ... , [SI] " beispielsweise, ohne die Angabe des Segmentregisters.
Ja genau und das bedeutet, das bei einem "mov ax, ds:[si]" das "ds:" keinen Sinn macht.
Aber bei einem "mov ax, ds:[bp]" macht es Sinn, weil BP als Adressregister verwendet defaultmäßig zum Stacksegment-Register(SS) zugeordnet ist.
Und das scheint auch die richtige Vorgehensweise zu sein, wenn man
durch Präfix ein anderes Segmentregister verwenden will, welches es
erst ab dem 386er gibt.
Aber auch ein "mov ax, es:[si]" macht schon auf einem 80286 einen Sinn.
Beispiel: " DB 64H ; MOV AX, [SI] " wird quasi zu " MOV AX, FS:[SI] " ?
Ja richtig.
Und wie ich das verstanden habe, kann man bis zu 4 Präfixbytes (in der
richtigen Reihenfolge) vor einen Befehl schreiben, um diesen genauer zu
bestimmen.
Das mit der genauen Reihenfolge muss ich selber noch einmal nachlesen. Der obige Online-Assembler hat mich diesbezüglich nun etwas verwirrt, weil er abweichend vom ASM86FAQ die Prefixe anordnet.

Dirk
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Pascal "absolute" Deklaration - mit Pointer-Array möglic

Beitrag von zatzen »

Ich hab damals, war ich 11 oder 12, mit QBASIC angefangen, war ja praktisch, war ja bei DOS dabei...
Und für den schnellen Erfolg als Abkürzung erstmal ganz nett.
1996 dann Pascal, das war allein schon wegen Blockread eine tolle Sache, jedenfalls hatte ich
bei Q(uick)BASIC keine eingebaute Möglichkeit gefunden, verschiedene Daten aus einer einzelnen
großen Datei zu holen (ausser in Strings). Dafür hab ich mir dann für meine alten Programme zwei
Jahre später eine Assemblerprozedur geschrieben, die aus einem Stringpuffer Daten in QBASIC Arrays
geschaufelt hat, die Daten waren in der "Gruppendatei" auch direkt RLE komprimiert.

Was die Präfixe (oder pre?) angeht, möglicherweise ist die Reihenfolge auch egal. Denn
der Prozessor muss ja jedes davon auch einzeln identifizieren können.

Als Disassembler hab ich mir vor kurzem auf die Schnelle IDA Pro Free geladen, damit hab
ich schonmal rausgefunden dass eine mit ASSEMBLER deklarierte Procedure/Function von
Pascal keinen Stackrahmen bekommt, gut zu wissen.

Ansonsten hab ich auch letztens nochmal in meinen alten Sachen rumgekramt wo ich mir
in Pascal etwas kleines in Assembler geschrieben habe mit Markierungsbytes vor und nach
dem Code, um das hinterher auszuschneiden und als .COM zu speichern. War auch eine
schöne Kunst, so ein puristisches Executable... Oder gab's da noch mehr zu beachten?
Naja, ich hab auch mal sowas wie ein "Hacktro" als .COM gemacht, also umfangreicher
(dann aber doch mit TASM), VGA Grafik, Scroller, Feuereffekt und AdLib Musik, hat
auch funktioniert, aber bei dem Code bin ich noch nicht so auf Optimierung konzentriert
rangegangen.
Muss ich mir nochmal ansehen, ist jetzt 15 Jahre her. Vielleicht habe ich damals schon
Dinge gemacht, nach denen ich heute wieder frage. Aber ich wusste damals noch wenig
über die Schnittstellen innerhalb Pascal, also Parameterübergabe und Stack-Bedingungen.

Ich hab "Das Assembler Buch" von Trutz Eyke Podschun. Damit kommt man gut zurecht,
aber es ist nicht so sehr darin beschrieben, wie man möglichst schnellen Code erzeugt.

Englisch ist kein Problem, zumindest der Input. Nach der Schule ging das auch wie von
selbst wegen Internet... Ansonsten gibt's ja auch Online-Wörterbücher.
Eigentlich dekadent, würde ja offline genauso gut taugen.
Aber sicher, erstmal lernt man in der Schule längst nicht alle Vokabeln, und an
schnell und flüssig gesprochenes Englisch in diversen Dialekten muss man sich
auch erstmal gewöhnen.

Ich kenne mich da nicht so detailliert aus, aber ich denke mal, Windows-Anwendungen
werden fast nur noch in Hochsprache geschrieben (wer will heute noch nicht-Objekt-orientiert
programmieren?), und die Hardware-Routinen verwendet man global. DirectX und so.
Wenn das wirklich so ist, könnte DOS theoretisch Windows immer um eine Nasenlänge voraus
sein was Geschwindigkeit betrifft, wenn die Geschwindigkeitskritischen Routinen direkt
integriert sind. Das findet man heute in 32/64 Bit vielleicht noch in der Demoszene.
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Pascal "absolute" Deklaration - mit Pointer-Array möglic

Beitrag von zatzen »

Okay ich hab in den alten ASM Sourcecode reingeguckt. Tatsächlich habe ich da etwas sehr umfangreiches
geschrieben, allerdings wirklich eher unbeholfen, in Hinblick auf Optimierungen. cmp al, 0 innerhalb einer
zeitkritischen Schleife und sowas... Auch schien ich damals nicht ganz überblickt zu haben, dass man
CS besser wirklich nur für Code benutzt, und dass man für Daten DS, ES & Co. hat, mit entsprechend
anders belegten Bereichen fernab vom Code-Segment.
Meine heutigen Fragen sind also keineswegs unsinnig sondern geben mir solides Hintergrundwissen.

Eine Sache, die bei reinem Assembler-Programmieren anders als bei Hochsprachen ist, ist wohl,
wie man den Speicher nutzt. Soetwas wie GETMEM gibt es wohl nicht, und man muss selber aufpassen
wie man den Speicher nutzt. Aber ich habe auch nicht vor, sonderlich vieles in reinem ASM zu machen.

Damals hat mir eine umfangreiche Liste über BIOS-Funktionen sehr geholfen. Sind diese generell Standard oder
auch DOS-bezogen?
mov ax, 13h
int 10h

while vorne_frei do vor;
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Pascal "absolute" Deklaration - mit Pointer-Array möglic

Beitrag von DOSferatu »

BIOS ist nicht DOS. BIOS ist vorher da. (Es gibt natürlich auch INTs, die direkt von DOS zur Verfügung gestellt werden.)
ABER: BIOS ist 16bit programmiert (damit es gleich funktioniert, wenn der Rechner startet). Kann man nicht direkt benutzen, wenn man sich im 32bit-Mode (PM) befindet, bzw nur dann, wenn man zwischendurch dafür in 16bit Mode schaltet.
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Pascal "absolute" Deklaration - mit Pointer-Array möglic

Beitrag von freecrac »

zatzen hat geschrieben:Soetwas wie GETMEM gibt es wohl nicht, und man muss selber aufpassen
wie man den Speicher nutzt.
Doch man kann Speicher von DOS anfordern. Dafür muss der restliche Speicher jedoch erst wieder freigegeben werden, weil unsere Anwendung den gesamten Speicher beim Starten von DOS zugewiesen bekam.

Code: Alles auswählen

          call SETFREE             
          mov      bx, 2000h         ; 128 KB anfordern/reservieren
          call GETSPACE              ; benötigten SPEICHER ANFORDERN:
          jc  NOSPACE                ; keine 128 KB        = Fehler !
;         .....
;         .....

;--------------------------------------------
SETFREE:  mov      bx, ss            ; zunächst die beiden Segmentadressen
          mov      ax, es            ; voneinander abziehen. Das ergibt die
          sub      bx, ax            ; Anzahl der Paragraphen vom PSP bis
                                     ; zum Anfang des Stack
          mov      ax, sp            ; da sich der Stackpointer am Ende des
          add      ax, 0Fh           ; Stacksegments befindet, gibt sein
          shr      ax, 4             ; Inhalt die Länge des Stacks an
          add      bx, ax            ; zur bisherigen Länge hinzuaddieren
          mov      ah, 4Ah           ; neue Größe an das DOS übergeben
          int    21h
          ret
;--------------------------------------------
GETSPACE: mov      ah, 48h           ; anfordern/reservieren:  BX = Anzahl/16
          int    21h
          ret
Dirk
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Pascal "absolute" Deklaration - mit Pointer-Array möglic

Beitrag von zatzen »

Danke, da muss ich mich etwas reinknien um das zu verstehen.
In besagtem Progrämmchen habe ich den Speicher so berechnet:

Code: Alles auswählen

	mov	bx, cs		; Codesegment + 4096 gibt
	add	bx, 01000h	; Anfang der Speicheraddresse,
	mov	ax, 0a000h	; ab der man den Speicher
	sub	ax, bx		; frei benutzen darf
	cmp	ax, 8230	; 8230*16 Byte frei?	
				; Ben”tigter Speicher:
				; - 64000 Byte [vscreen]
				; - 57344 Byte [Zeichensatz]
				; - 160*24 Byte [FlameBuffer]
				; - 128*14 Byte [LogoBuffer]
                                ; - 14*16*21 Byte [scrollbuf]

	jae     genug_frei

Warum Speicher ab Codesegment + 4096 benutzbar ist, ist mir gerade nicht klar.
Mögllicherweise liegts an der ASM-Anweisung "org 100h". Als quasi "GETMEM" habe ich
mich darauf beschränkt, die Segmente richtig zuzuweisen, ohne jegliche Reservierung.
Für kleine Projekte ohne Anspruch auf dynamischen Speicher ist das wohl auch kein Problem.
mov ax, 13h
int 10h

while vorne_frei do vor;
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Pascal "absolute" Deklaration - mit Pointer-Array möglic

Beitrag von freecrac »

zatzen hat geschrieben:Danke, da muss ich mich etwas reinknien um das zu verstehen.
Programmlänge+Größe des Stacks = Von unserem Programm benötigter Speicher. Der Rest kann an DOS zurückgegeben werden. Und danach können wir eine bestimme Menge an Speicher anfordern und bekommen einen zusammen hängenden Speicherbereich der garantiert noch unbenutzt ist, oder falls diese Speichermenge nicht vorhanden ist bekommen wir eine Fehlermeldung.
In besagtem Progrämmchen habe ich den Speicher so berechnet:

Code: Alles auswählen

	mov	 bx, cs		; Codesegment + 4096 gibt
	add 	bx, 01000h	; Anfang der Speicheraddresse,
	mov	 ax, 0a000h	; ab der man den Speicher
	sub 	ax, bx		; frei benutzen darf
	cmp 	ax, 8230	; 8230*16 Byte frei?	
				; Ben”tigter Speicher:
				; - 64000 Byte [vscreen]
				; - 57344 Byte [Zeichensatz]
				; - 160*24 Byte [FlameBuffer]
				; - 128*14 Byte [LogoBuffer]
                                ; - 14*16*21 Byte [scrollbuf]

	jae     genug_frei

Warum Speicher ab Codesegment + 4096 benutzbar ist, ist mir gerade nicht klar.
Mögllicherweise liegts an der ASM-Anweisung "org 100h". Als quasi "GETMEM" habe ich
mich darauf beschränkt, die Segmente richtig zuzuweisen, ohne jegliche Reservierung.
Für kleine Projekte ohne Anspruch auf dynamischen Speicher ist das wohl auch kein Problem.
Aber 1 MB Ram Speicher sollte dann zumindest auch vorhanden sein, weil das war in den Anfangszeiten ja auch nicht selbstverständlich. Ich glaube ich habe selber nur mit 128 KB SIP-Modul MS DOS 4 das erste mal gebootet.

Dirk
Antworten