Liebes Forum, wie vielleicht der ein oder andere bemerkt har,
beschäftige ich mich derzeit mit PC Programmierung unter DOS. Einfach
weil man da so nah an der Hardware ist und im ganzen Speicher
umeinanderpointern kann, soweit man ihn denn adressieren kann.
Mittlerweile hab ich einen PnP Hardware Scanner in Turbo C++
(Beitrag "Speicherdump mithilfe von C unter DOS erstellen") und einen PCIe Bus
Scanner mit SmallerC (Beitrag "PCI Express Memory Mapping")
geschrieben. Jetzt versuche ich mithilfe von Forth über die IO-Ports
(0xcf8 und 0xcfc) auf meine PCI Hardware zuzugreifen.
Es kommt ja immer irgendwann die Qual der Wahl eines Compilers. Hier ist
meine Wahl auf FPC bzw. TCOM von Tom Zimmer gefallen und zwar deshalb,
weil sich mit TCOM Ausführbare Dateien im COM Format erstellen lassen.
Das Erstellen von standalone Programmen mit Forth ist ja leider nicht
ganz trivial.
Der Haken an der Sache ist nur, dass FPC und TCOM für 8086 geschrieben
wurden und der Zugriff auf PCI via Ports ein 32-Bit AX bzw. EAX Register
zu brauchen scheint. Deshalb habe ich, bis jetzt leider erfolglos,
versucht das Operand Size Override Prefix 0x66 ins Wörterbuch zu
pfriemeln. Es scheint mir allerdings so, als dass das einfach eine
Konstante geworden ist. Zur Verwendung von CREATE DOES> hab ich leider
auch nur Beispiele für Variablen, Konstanten und Arrays gefunden. Hier
mal mein Versuch, der auf das was ich in FPCs PASM.SEQ gefunden habe
aufbaut:
1
: outz32 ( x -- ) create c, does> c@ ;
2
3
$66 outz32 oute32
4
5
code sendport ( -- ) mov dx, $cf8 ret end-code
6
7
code senddata ( -- ) mov ax, $80000000 ret end-code
8
9
code outx32 ( -- ) oute32 out dx, ax ret end-code
10
11
: main ( -- ) sendport senddata outx32 ;
Disassembled dann, gekürzt auf die Worte, ohne "Vorspann" und "Abspann":
1
; OUTZ32
2
01DC DEC SI 4E
3
01DD DEC SI 4E
4
01DE MOV 0 [SI], BX 891C
5
01E0 MOV BX, AX 8BD8
6
01E2 MOV BL, 0 [BX] 8A1F
7
01E4 SUB BH, BH 28FF
8
01E6 RET C3
9
; OUTE32
10
01E7 MOV AX, # 14 B81400
11
01EA JMP OUTZ32 E9EFFF
12
; SENDPORT
13
01ED MOV DX, [CF8 ] 8B16F80C
14
01F1 RET C3
15
; SENDDATA
16
01F2 MOV AX, DP A10000
17
01F5 RET C3
18
; OUTX32
19
01F6 OUT DX, AX EF
20
01F7 RET C3
21
; MAIN
22
01F8 CALL SENDPORT E8F2FF
23
01FB CALL SENDDATA E8F4FF
24
01FE CALL OUTX32 E8F5FF
25
0201 RET C3
26
0202 ADD 0 [BX+SI], AL 0000
27
0204 ADD 0 [BX+SI], AL 0000
28
0206 ADD 0 [BX+SI], AL 0000
29
0208 ADD 0 [BX+SI], AL 0000
30
020A ADD 0 [BX+SI], AL 0000
31
020C ADD 0 [BX+SI], AL 0000
32
020E ADD 0 [BX+SI], AL 0000
33
0210 ADC AX, # DP 150000
Der Compiler sagt auch es bleiben Daten am Stack, also genau mein 0x66.
Wie könnte ich die Definition von OUTX32 ändern, so das in Zeile 0x01f6
anstelle von 0xef ein 0x66ef steht?
Vielen Dank für Euere Hilfe.
Asterix schrieb:> Es kommt ja immer irgendwann die Qual der Wahl eines Compilers.
[...]
> Deshalb habe ich, bis jetzt leider erfolglos,> versucht das Operand Size Override Prefix 0x66 ins Wörterbuch zu> pfriemeln.
Spätestens, wenn man bemerkt, dass es unverhältnismäßig aufwendig wird,
mit dem gewählten Tool sein Ziel zu erreichen, sollte man die Wahl
dieses Tools noch einmal hinterfragen (und ggf. revidieren...)
Naja wie wäre es mit mov eax,$80000000 ?
Zusätzlich bin ich mir nicht so sicher ob eax generell unter dos
Realmode überhaupt funktionieren kann. Das musst du selber prüfen.
Thomas
Thomas schrieb:> Naja wie wäre es mit mov eax,$80000000 ?> Zusätzlich bin ich mir nicht so sicher ob eax generell unter dos> Realmode überhaupt funktionieren kann. Das musst du selber prüfen.>> Thomas
Genau das hab ich für IN, OUT und MOV vor. Um das zu bewerkstelligen
muss man, soweit ich weiß, nur das Operand Size Override Prefix
voranstellen.
c-hater schrieb:> Asterix schrieb:>>> Es kommt ja immer irgendwann die Qual der Wahl eines Compilers.> [...]>>> Deshalb habe ich, bis jetzt leider erfolglos,>> versucht das Operand Size Override Prefix 0x66 ins Wörterbuch zu>> pfriemeln.>> Spätestens, wenn man bemerkt, dass es unverhältnismäßig aufwendig wird,> mit dem gewählten Tool sein Ziel zu erreichen, sollte man die Wahl> dieses Tools noch einmal hinterfragen (und ggf. revidieren...)
Eigentlich dachte ich, dass es für Forth Profis ein Kinderspiel sei, ein
weiteres Byte in den Ausführungskanal zu bekommen. Im Grunde gehts mir
da auch um CREATE DOES> – weils ja die Essenz von Forth genannt wird.
Was mir als Neuling gerade nicht gelingt, ist es ein Wort zu definieren,
dass in seinem Codefeld 0x66efc3 stehen hat. Also OUT DX, EAX RET. Das
Prinzip dürfte sich dann hoffentlich auch auf IN und MOV Anwenden
lassen.
Asterix schrieb:> Eigentlich dachte ich, dass es für Forth Profis ein Kinderspiel sei, ein> weiteres Byte in den Ausführungskanal zu bekommen. Im Grunde gehts mir> da auch um CREATE DOES> – weils ja die Essenz von Forth genannt wird.> Was mir als Neuling gerade nicht gelingt, ist es ein Wort zu definieren,> dass in seinem Codefeld 0x66efc3 stehen hat. Also OUT DX, EAX RET. Das> Prinzip dürfte sich dann hoffentlich auch auf IN und MOV Anwenden> lassen.
Also, du kannst offensichtlich nicht "hinter den Zeilen" lesen. Also
deutlicher: Forth ist historisch. Kein Schwein interessiert das heute
noch ernsthaft.
Allenfalls im akademischen Umfeld (und dort auch nur bei den "Frischen")
poppt dieser Kram gelegentlich nochmal hoch. Alle anderen wissen nach
drei Jahrzehnten der "praktischen Anwendung": das braucht man echt
nicht.
Asterix schrieb:> PC Programmierung unter DOS.> ... 8086 ...
Ich denke mal du bist unter 16-bit 8086 (Realmodus) unterwegs. Da gab es
schlichtwegs noch kein EAX (32-bit) Register.
leo
leo schrieb:> Asterix schrieb:>> PC Programmierung unter DOS.>> ... 8086 ...>> Ich denke mal du bist unter 16-bit 8086 (Realmodus) unterwegs. Da gab es> schlichtwegs noch kein EAX (32-bit) Register.>> leo
Du vermischt Memorymodel und 386 Opcode support des compilers
c-hater schrieb:> Asterix schrieb:>>> Es kommt ja immer irgendwann die Qual der Wahl eines Compilers.> [...]>>> Deshalb habe ich, bis jetzt leider erfolglos,>> versucht das Operand Size Override Prefix 0x66 ins Wörterbuch zu>> pfriemeln.>> Spätestens, wenn man bemerkt, dass es unverhältnismäßig aufwendig wird,> mit dem gewählten Tool sein Ziel zu erreichen, sollte man die Wahl> dieses Tools noch einmal hinterfragen (und ggf. revidieren...)
Die anderen Tools von ihm sind ja in C geschrieben, ich denke Forth will
er einfach nur so zum spielen benutzen
c-hater schrieb:> Asterix schrieb:>>> Es kommt ja immer irgendwann die Qual der Wahl eines Compilers.> [...]>>> Deshalb habe ich, bis jetzt leider erfolglos,>> versucht das Operand Size Override Prefix 0x66 ins Wörterbuch zu>> pfriemeln.>> Spätestens, wenn man bemerkt, dass es unverhältnismäßig aufwendig wird,> mit dem gewählten Tool sein Ziel zu erreichen, sollte man die Wahl> dieses Tools noch einmal hinterfragen (und ggf. revidieren...)
Die anderen Tools von ihm sind ja in C geschrieben, ich denke Forth will
er einfach nur so zum spielen benutzen
^
c-hater schrieb:> Forth ist historisch. Kein Schwein interessiert das heute> noch ernsthaft.
DOS ist genauso historisch, real mode x86 ausserhalb von BIOS und
Bootloadern ebenfalls. Und ihn interessiert es offenbar.
cppbert3 schrieb:> Du vermischt Memorymodel und 386 Opcode support des compilers
Im Realmode geht der prefix einfach nicht das werden also nie 32 Bit
Befehle.
Thomas
Das stimmt nicht, man kann 32 Bit Register im Real Mode benutzen. Dazu
dient ja das Operand Size Prefix. Man kann aber nicht einfach so (geht
schon, aber nicht einfach so) z.B. über EDI mehr als 64k Speicher
adressieren, da grob gesagt per default Addressen grösser 64k maskiert
werden.
Das könnte evtl. auch ein Problem mit in/out und EDX als Operand werden,
aber bin nicht sicher.
Lang ist's her.
c-hater schrieb:> Allenfalls im akademischen Umfeld (und dort auch nur bei den "Frischen")> poppt dieser Kram gelegentlich nochmal hoch. Alle anderen wissen nach> drei Jahrzehnten der "praktischen Anwendung": das braucht man echt> nicht.
Da du dich – ausgerechnet hier – c-hater nennst würde mich echt brennend
interessieren in welchen Sprachen du programmierst. Mit deiner
Einschätzung zu mir liegst du jedenfalls richtig, ich bin Student.
Asterix schrieb:> Da du dich – ausgerechnet hier – c-hater nennst würde mich echt brennend> interessieren in welchen Sprachen du programmierst.
In der Reihenfolge der Häufigkeit (nach rein dienstlich geschreibenen
Programmzeilen) im letzen Jahr:
VB.net
T-SQL
C#
C
Assembler
Java
C++
PostGre-SQL
Perl
(weitere 10 Sprachen...)
Tja, im Job kann man nicht immer seinen Vorlieben frönen, da taucht dann
C schonmal an 4. Stelle auf, selbst wenn man die Sprache (aus guten
Gründen) hasst wie die Pest. Nur was man wirklich kennt, kann man so
dermaßen abgrundtief hassen lernen, vor allem, wenn man auch Besseres
kennt...
Privat sieht das deshalb auch etwas anders aus:
VB.net
Assembler
T-SQL
bash-Scripting
(ansonsten nix in nennenswertem Umfang...)
Ich würde sagen, Deine code, end-code Zeilen müssen sich in einer
Wortdefinition befinden, sonst werden sie nur in der compile-time
ausgeführt oder so. Ist aber schon länger her bei mir.
Beim Inline Assembler in Forth sind die Argumente umgetauscht.
(Operand, Operator, wie hieß das andere noch mal?)
Also aus mov a,b wird mov b,a oder z.B. b,a mov.
Ich weiß auch keinen Grund, warum in einer code,end-code Zeile keine
simplen Bytes stehen können.
Die von mir erwähnten Sachen solltest Du mal kontrollieren.
Versuche auch erst einmal, das Problem zu isolieren.
Einen Haufen Komplexitäten kannst Du auch behalten.
Was findest Du nicht in der Dokumentation, oder gibt es gar keine?
Empfehlung dazu: Wenn Du gut in C schreiben kannst, nimm davon den
Inline Assembler.
Im übrigen kannst Du ohne protected mode bei einem X386 und aufwärts
durchaus
32bit Code verwenden.
Übrigens ratet mal, was mir bei der Suche nach "TCOM" ins Auge springt.
FPC ergibt auch nichts sinnvolles(Free Pascal Compiler?).
Matthias K. schrieb:> Übrigens ratet mal, was mir bei der Suche nach "TCOM" ins Auge springt.> FPC ergibt auch nichts sinnvolles(Free Pascal Compiler?).
Dank Dir hab ich diese Seite gefunden http://forth.org/eforth.html
vorher war ich nur dort http://forth.org/compilers.html unterwegs.
Lesson 3 von Richard E. Haskell scheint mir den Weg zum Ziel zu deuten.
Da werd ich mal ansetzen.
c-hater schrieb:> Asterix schrieb:>>> Da du dich – ausgerechnet hier – c-hater nennst würde mich echt brennend>> interessieren in welchen Sprachen du programmierst.>> In der Reihenfolge der Häufigkeit (nach rein dienstlich geschreibenen> Programmzeilen) im letzen Jahr:
An der Uni brauch ich nur MATLAB. Früher an der Schule wurde mal C#
gelehrt. Naja, und die alten TI BASIC Programme fürn Taschenrechner kann
man hier noch mitzählen. Das wurde zwar nicht gelehrt, hatte allerdings
seine Vorteile. Grad in Anbetracht dessen, dass die Lehrer den
Taschenrechner nicht begriffen haben.
Privat steht C an erster Stelle. Shell Skripten nehmen auch viel mehr
Raum ein als ich zuerst dachte. Dann wohl C++, Scheme, Forth, Fortran,
Ada.
Am besten kann ich C. Da es im Vergleich ja doch noch überschaubar ist.
Um mal eine Anektode zu erzählen – als junger Mensch dachte ich noch,
dass das Programmieren einfach viel mit Klammern zu tun hat. Wegen all
der runden, geschweiften, eckigen und spitzen Klammern in C, Java, C++,
C#, D und wie sie sonst noch heißen in der C Sprachfamilie. Eigentlich
hab ich das was ich sah und mir beigebracht wurde als lineare
Entwicklung aufgefasst. Ganz früher Assembler, dann C, danach C++ und
heut C# um das mal vereinfacht darzustellen.
Sprachen wie Scheme und Forth musste ich erst entdecken, da sie
heutzutage an der "Oberfläche" gar nicht mehr zu sehen sind. Dabei ist,
zumindest für mich, die Einheitlichkeit von Scheme Code mit großer
Ästethik verbunden. Forth hingegen gibt mir die Freiheit meine Worte
x-beliebig zu nennen. Es kennt nur Worte und Zahlen. Klammern sind dort
auch nur Worte. Sogar das alte TCOM hat mir schon ein UTF-8 codiertes
'ä' ohne zu murren in einen Wortnamen kompiliert.
Es ist einfach Schade, dass Konzepte wie call/cc in Scheme oder CREATE
DOES> in Forth nur mit ihren einfachsten Beispielen einer breiteren
Öffentlichkeit vorgestellt werden. Da ich wohl auch nicht der hellste
Stern am Nachthimmel bin, ist mir die beschworene Mächtigkeit von
call/cc anhand von setjmp(), longjmp() oder CREATE DOES> was als
Hilfsmittel zur Deklaration von Konstanten, Variablen und Arrays
dargestellt wird, nicht klar geworden.
Dabei hat mir Forth schon am ersten Tag den Gendanken beschert, man
könne in dieser Sprache seine Programme in Gedichtform verfassen.
Max schrieb:> Haha vb als #1^^> Disqualifiziert!
Idiot!
1) VB.net != VB
2) VB.net == C# abgesehen von einer wesentlich angenehmeren Syntax,
nicht
nur für den Programmierer, sondern vor allem auch für
die
Kontext-bezogenen Hilfsmittel des VS, insbesondere
IntelliSense kann dank der höheren Redundanz der Sprache
sehr
viel schneller und treffsicherer arbeiten.