Forum: PC-Programmierung DOS,16Bit:Ich suche DOS sys Treiber Beispiel Source


von cppbert3 (Gast)


Lesenswert?

Ich suche Beispielcode für einen DOS Sys Treiber - wenn möglich für 
Turbo/Borland C/C++ oder Watcom, ist für ein Reverse Engineering Projekt

Ich hab eine paar Links, Dr Dobbs,... und ein paar PDFs gefunden aber 
fast alles ist Asemblercode - da weiss ich wie ich eine Sys Treiber 
baue, nur finde ich nichts für pure C - falls das überhaupt ganz ohne 
Assembler möglich ist

von Marc (Gast)


Lesenswert?

Ich vermute, das damals viel mit Inline Assembler gearbeitet wurde, DOS 
war ja ziemlich nah an der Hardware im Vergleich zu modernen 
Betriebssystemen.

von Peter M. (r2d3)


Lesenswert?

Hallo cppbert3,

cppbert3 schrieb:
> Ich suche Beispielcode für einen DOS Sys Treiber - wenn möglich
> für
> Turbo/Borland C/C++ oder Watcom, ist für ein Reverse Engineering Projekt

eventuell findest Du etwas im Sourcecode von Truecrypt.

von cppbert3 (Gast)


Lesenswert?

Marc schrieb:
> Ich vermute, das damals viel mit Inline Assembler gearbeitet
> wurde, DOS war ja ziemlich nah an der Hardware im Vergleich zu modernen
> Betriebssystemen.

Wie schon geschrieben, habe ich schon Dos sys Treiber in Assembler 
programmiert, mein Problem ist die Sprungtabelle usw. am Anfang der Sys 
Datei, mir ist nicht klar wie ich das in C hin bekomme oder was ich für 
Linkersettings brauche

von cppbert3 (Gast)


Lesenswert?

Peter M. schrieb:
> Hallo cppbert3,
> eventuell findest Du etwas im Sourcecode von Truecrypt.

Truecrypt ist Erstrelease 2004, das ist lange lange nach der 16 Bit DOS 
Zeit, ich denke das ist technologisch was völlig anderes

von Rolf M. (rmagnus)


Lesenswert?

Bei FreeDOS sind Treiber dabei, die man sich anschauen kann. Findet man 
hier:
http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.2/repos/pkg-html/group-drivers.html

Allerdings wird das wahrscheinlich auch größtenteils alles Assembler 
sein.

von Oliver S. (oliverso)


Lesenswert?

cppbert3 schrieb:
> Ich hab eine paar Links, Dr Dobbs,...

https://www.drdobbs.com/writing-ms-dos-device-drivers/184402277

Das alles klingt nicht sehr vielversprechend, um es mit den damals 
verfügbaren tools in C hinzukriegen.

Da das aber damals in Assembler alles machbar war, sollte das heute auch 
noch so sein.

Oliver

von cppbert3 (Gast)


Lesenswert?

Oliver S. schrieb:
> Da das aber damals in Assembler alles machbar war, sollte das heute auch
> noch so sein.

Es ist so

von G. O. (aminox86)


Lesenswert?

cppbert3 schrieb:
> Ich suche Beispielcode für einen DOS Sys Treiber - wenn möglich
> für
> Turbo/Borland C/C++ oder Watcom,
Das dürfte passen:
Adams/Tondo - Treiberprogramme in C unter Dos
ISBN 3-446-16391-3

von cppbert3 (Gast)


Lesenswert?

vielleicht muss es auch nicht unbedingt ein DOS Geräte-Treiber sein

im Grunde will ich mit C ein Binary erzeugen welches bei Offset 0 eine 
far-Jump Tabelle enthält - dieser "drv" wird dann von einer alten 
DOS-Applikation geladen welche dann direkt far calls auf die 
Tabellen-Punkte macht um die entsprechenden Treiber-Funktionen 
aufzurufen

hier ein assemblierbares Beispiel (nur mit weniger/trivial Funktionenals 
in echt)

Wichtig:
-der Jump/Call-Table muss exakt an der Stelle liegen
-es müssen Far-Funktionen als Ziele sein
-alle Variablen werden per cs-Register adressiert
sonst laeuft das nicht mit der Original-Applikation

den Original-Treiber habe ich vollständig reverse engineering und möchte 
den jetzt nach C portieren
1
;----------------------------------------
2
; Realmode, 16Bit
3
; some sort of loadable library binary image with no entry point 
4
; but a 2 functions jump-table starting at offset 0
5
;
6
; this drv file gets dynamically loaded into its own segment
7
;
8
; all data is addressed by the CS-Register
9
;
10
; how to build:
11
;
12
; assembler: current ML (for example from VS2019) or UASM (http://www.terraspace.co.uk/uasm.html)
13
; linker: UniLinker (ftp://ftp.styx.cabel.net/pub/UniLink/ulnb1155.zip) (or later)
14
;
15
; assemble:
16
;   ml.exe /c /omf drv.asm
17
;   or
18
;   uasm64.exe drv.asm
19
; link:
20
;   ulink.exe -T16 -Tbi drv.obj, drv.drv
21
;----------------------------------------
22
23
seg000    segment byte public 'CODE' USE16
24
    org 0
25
    assume cs:seg000
26
    assume es:nothing, ss:nothing, ds:nothing
27
28
;----------------------------------------
29
; no entry point:
30
; there is no fixed first code to run and no (exe or whatever) header to put in the entry point address
31
32
; needed for UniLinker
33
; i can't find an option that allows to create an no-entry-point binary image (-e- does not work with DOS applications)
34
dummy_entry_point:
35
;----------------------------------------
36
37
;----------------------------------------
38
; jump table with 2 functions (far called by the drv loading program)
39
; "interface" of the driver
40
;----------------------------------------
41
    jmp near ptr tsub0
42
; ---------------------------------------------------------------------------
43
    jmp near ptr tsub1
44
; ---------------------------------------------------------------------------
45
46
; data
47
48
value1    db 0
49
value2    dw 0
50
51
; some internal functions
52
53
isub0   proc near
54
    mov cs:value1, 123
55
    retn
56
isub0   endp
57
58
isub1   proc near
59
    mov cs:value2, 321
60
    retn
61
isub1   endp
62
63
; interface implementer
64
65
tsub0   proc far
66
    call isub0
67
    retf
68
tsub0   endp
69
70
tsub1   proc far
71
    call isub1
72
    retf
73
tsub1   endp
74
75
seg000    ends
76
end dummy_entry_point

von cppbert3 (Gast)


Lesenswert?

vielleich auch nur ein kleiner Stub in Assembler für den Table und dann 
ein C Objekt mit dem Code dazu linken, ohne C-Runtime? aber wie bekomme 
ich dann die Variablen CS-Register adressiert?

von Georg (Gast)


Lesenswert?

Oliver S. schrieb:
> Da das aber damals in Assembler alles machbar war, sollte das heute auch
> noch so sein.

Möglich ist es schon, aber nicht für jeden. Und von "modernen" 
Programmierern wird das grundsätzlich abgelehnt. Ist wie beim Fuchs mit 
den sauren Trauben oder so ähnlich.

Wichtig ist dabei die Schnittstelle von C zu Assembler- (oder sonstwas) 
Unterprogrammen, die muss in der Compiler-Linker-Dokumentation 
beschrieben sein. Wenn nicht hat man gleich ganz schlechte Karten. Wie 
das bei Turbo-C war kann ich mich nicht mehr erinnern.

Georg

von Peter M. (r2d3)


Lesenswert?

Hallo IgNorbert3,

cppbert3 schrieb:
> Peter M. schrieb:
>> Hallo cppbert3,
>> eventuell findest Du etwas im Sourcecode von Truecrypt.
>
> Truecrypt ist Erstrelease 2004, das ist lange lange nach der 16 Bit DOS
> Zeit, ich denke das ist technologisch was völlig anderes

warum bist Du so ignorant?
Ich denke, also irre ich!

Was ich Dir schrieb, betrifft nicht nur Truecrypt, sondern auch das ach 
so moderne Veracrypt.

Lies' hier und krieche zu Kreuze!

[...
Last point : the code of VeraCrypt BIOS boot loader runs in a restricted 
environment with limited resources and legacy mode (16-bit), which make 
all cryptographic computation slower. Once Windows is started, we go 
back to normal more with no performance degradation.
We can do nothing about this. In the future, we plan to support UEFI 
boot which enables the use of more resources for booting.
...]

https://sourceforge.net/p/veracrypt/discussion/technical/thread/77d58591/

von cppbert3 (Gast)


Lesenswert?

Peter M. schrieb:
> warum bist Du so ignorant?
> Ich denke, also irre ich!

Warum bist du so empfindlich? Ich war nicht ignorant obwohl ich denke 
das du keine Ahnung von dem hast was ich weiter oben so gepostet habe

Peter M. schrieb:
> Lies' hier und krieche zu Kreuze!
> [...
> Last point : the code of VeraCrypt BIOS boot loader runs in a restricted
> environment with limited resources and legacy mode (16-bit), which make
> all cryptographic computation slower. Once Windows is started, we go
> back to normal more with no performance degradation.
> We can do nothing about this. In the future, we plan to support UEFI
> boot which enables the use of more resources for booting.
> ...]
> https://sourceforge.net/p/veracrypt/discussion/technical/thread/77d58591/

Es geht mir um ein sehr konkretes Problem zu dem ich sogar 
funktionierenden Assemblercode gezeigt habe, das hat mit einem 16 bit 
bootloader eines krypters nicht mehr gemeinsam als das ähnliche 
Schlagworte vorkommen

Beitrag #6632763 wurde von einem Moderator gelöscht.
von Peter M. (r2d3)


Lesenswert?

Werter cppbert3,

cppbert3 schrieb:
> Es geht mir um ein sehr konkretes Problem zu dem ich sogar
> funktionierenden Assemblercode gezeigt habe, das hat mit einem 16 bit
> bootloader eines krypters nicht mehr gemeinsam als das ähnliche
> Schlagworte vorkommen

Assemblercode taucht in Deinem Eingangsbeitrag nicht auf.
Ich musste mich daher mit Deinen wenigen Sätzen bescheiden.

Mein Seher ist in Urlaub, und die Kristallkugel in Reparatur.

Eine lustige Antwort von Dir, die mir unterstellt, dass ich 
Informationen von Dir ignoriert hätte, die zu dem Zeitpunkt gar nicht 
vorhanden waren.

Timing kann bei Assemblerproblemen durchaus eine Bedeutung haben.

Unter einem laufenden Windows-Betriebssystem zählt der entsprechende 
Code wohl als "Filtertreiber".

Dir zuliebe nenne ich den Code, der die gleiche Aufgabe beim Systemstart 
wahrnimmt nun "Bert-Minus-Minus-Code". Wir wollen das Kind doch nicht 
bei seinem eigentlichen Namen nennen! :)

: Bearbeitet durch User
von cppbert3 (Gast)


Lesenswert?

Peter M. schrieb:
> Assemblercode taucht in Deinem Eingangsbeitrag nicht auf.
> Ich musste mich daher mit Deinen wenigen Sätzen bescheiden.

Bei deinem Folgenpost stand der Assemblercode schon lange da

Wenn du mir helfen kannst dann mach es bitte konkret mit Fragen oder 
Ideen, aber beschwer dich nicht wenn dein dann doch etwas zu allgemeiner 
Tips bei mir nicht den Anklang finden den du erwartet hast und falls du 
keine Ahnung von Assembler und C Linkage hast ist ist es höchst 
wahrscheinlich schwer mir zu helfen, ich entschuldige mich im Vorfeld 
falls du doch tiefe Assembler/C Kenntnisse hast

von cppbert3 (Gast)


Lesenswert?

Peter M. schrieb:

> Timing kann bei Assemblerproblemen durchaus eine Bedeutung haben.

> Unter einem laufenden Windows-Betriebssystem zählt der entsprechende
> Code wohl als "Filtertreiber".

Was auch immer die beiden Statements mit meinem Problem zu tun haben
- sollte dir unklar sein was der obige Assemblercode macht ist das 
einfach nicht der Platz um grobes PC wissen zur Schau zu stellen

von linker Linker (Gast)


Lesenswert?

cppbert3 schrieb:
> im Grunde will ich mit C ein Binary erzeugen welches bei Offset 0 eine
> far-Jump Tabelle enthält

Du kannst die Ablage im Speicher per Linker koordinieren. Schau mal in 
die Beschreibung von TLink.

von rbx (Gast)


Lesenswert?

Ich fühle mich hier erinnert an den Artikel "Assembler to C" von Walter 
Bright.
https://www.digitalmars.com/articles/b43.html

Da gab es glaube ich, auch noch etwas mehr dazu, finde ich aber nicht 
mehr.

Ein anderes Projekt ist der Midnight Commander von Miguel de Icaza - der 
den Dos - Norton Commander (asm) in C geclont hatte.

Microsoft wollte ja auch von Dos wegkommen und hatte dafür u.a. directx 
entwickelt.

Dann gibt es Dos-Programme/Rechner, die DPMI nicht abkönnen - aber so 
manches Dos-Programm braucht die Erweiterung auf z.B. Unreal-Mode z.B. 
oder eben ein Protected Mode Interface.

Bei einfachen 16-Bit Sachen muss der Linker das schwierige Real 
Mode-Handling betreiben - ohne dem wird das nix mit far-jumps.

Die Watcom-Programme laufen auf 16 Bit - und auf 32 Bit d.h. auch auf 
Windows 8. obwohl bei mir 64 Bit.
Auch dieses ist zu berücksichtigen: die Portabilität nach wohin genau?

Es gibt z.B. auch neuere Bibliotheken, so dass ältere Compiler gar nicht 
mehr auf älteren Kisten laufen bzw. gar nicht mehr aufwärts-compatibel 
sind.

von cppbert3 (Gast)


Lesenswert?

rbx schrieb:
> Ich fühle mich hier erinnert an den Artikel "Assembler to C" von
> Walter
> Bright.
> https://www.digitalmars.com/articles/b43.html

den Artikel kenne ich

keine Ahnung was deinen anderen Sätze nur im entferntesten mit meinem 
Topic zu tun haben - ausser das es irgendwie mit DOS und 16Bit zu tun 
hat

ich mach nichts mit Windows oder DirectX, DPMI oder DOS/Windows 
Portierung sondern will eine DOS-Code den ich disassembliert habe von 
Assembler nach C portieren - das Ergebnis läuft aber weiterhin unter DOS

und der Linker hat mit der far/near/Real-Mode Segmentierungs-Sache bis 
auf das zuordnen der passenden Symbole keine Bedeutung - das muss alles 
der Kompiler machen

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

> von Assembler nach C portieren
Aber sonst bist Du gesund?

von Julius (Gast)


Lesenswert?

Soweit ich verstanden habe geht es ja nur darum wie man eine 
Sprungtabelle in C programmiert. Dafür könntest Du dir auch den 
C-Startup-Code von heutigen ARM Cortex-M3 Mikrocontroller ansehen. Bei 
dem Keil uVision MDK for ARM ist entsprechender Code mit enthalten, oder 
es könnte auch Beipsiele im Netz irgendwo geben.

von cppbert3 (Gast)


Lesenswert?

Julius schrieb:
> Soweit ich verstanden habe geht es ja nur darum wie man eine
> Sprungtabelle in C programmiert.

nur die Sprung-Tabelle ist nicht soo schwer, das ich aber meine Daten in 
C/C++ per CS oder Umwege DS adressiert bekomme scheint schwierig

Julius schrieb:
> Dafür könntest Du dir auch den
> C-Startup-Code von heutigen ARM Cortex-M3 Mikrocontroller ansehen. Bei
> dem Keil uVision MDK for ARM ist entsprechender Code mit enthalten, oder
> es könnte auch Beipsiele im Netz irgendwo geben.

ist das in dem Umfeld nicht alles super spezialisiert und lässt sich 
kaum auf mein MS-DOS 16 Bit Umfeld mappen?

von cppbert3 (Gast)


Lesenswert?

Ben B. schrieb:
>> von Assembler nach C portieren
> Aber sonst bist Du gesund?

alle paar Jahre packt mich die Assembler-Lust und da ich beruflich u.a. 
auch im Reverse-Engineering tätig bin - dort aber selten mit alten 
Systemen zu tuen haben ist es schon eine Form von krankhaftem 
Masochismus der mich treibt :)

von cppbert3 (Gast)


Lesenswert?

ich bin jetzt von der Idee abgekommen alles vollstaendig in C zu machen
d.h. ich schreiben den Jump-Table in Assembler und verweise auf externe 
far Functionen in C/C++

Assembliert, kompiliert und linkt auch - alles ganz toll

ABER

Jetzt werden meine Variablen in C/C++ nicht richtig adressiert:

1. der Zugriff passiert per DS-Register - obwohl durch den Plugin-Caller 
aber nur CS verfuegbar ist (ich koennte ds=cs+? setzen)
2. der Linker geht irgendwie davon aus das meine C/C++ Variablen in 
einem freien Segment vorliegen deswegen sind
die Variablen-Offsets beim Zugriff falsch

die alte DOS-Applikation macht diese komischen Vorgaben (Daten nur per 
CS erreichbar, und eben dieser Jump-Table) daran kann ich nichts
aendern

ich würde es sehr gerne vermeiden die Variablen in den Assembler-Code zu 
stellen - vielleicht hat ja jemand noch eine Idee

Was ich bisher haben:

Assembler-Code (Stellt sicher das der Jump-Table den DOS Plugin-Vorgaben 
entspricht)

drv_asm.asm
1
seg000 segment byte public 'CODE' USE16
2
  org 0 ; das Plugin hat bei Offset 0 den Jump-Table
3
  assume cs:seg000, es:nothing, ss:nothing, ds:nothing
4
5
dummy_entry_point: ; for the linker
6
7
; ---------------------------------------------------------------------------
8
; jump table aka "interface", far called by the "plugin" loading program
9
  jmp near ptr _tsub0
10
  jmp near ptr _tsub1
11
  ; jmp near ptr _tsub2
12
  ; ... around 20 function jumps
13
; ---------------------------------------------------------------------------
14
15
extrn _tsub0:far
16
extrn _tsub1:far
17
; extrn _tsub2:far
18
; ...
19
20
seg000 ends
21
22
end dummy_entry_point

drv_cpp.cpp
1
static int value1 = 10;
2
static int value2 = 11;
3
4
extern "C" {
5
  void far tsub0()
6
  {
7
    value1 = 20;
8
  }
9
  
10
  void far tsub1()
11
  {
12
    value2 = 22;
13
  }
14
}

Build-Script (Tools laufen alle unter Windows x64):

build.cmd
1
rem UASM: http://www.terraspace.co.uk/uasm.html
2
set uasm_exe=D:\rev_eng\uasm249_x64\uasm64.exe
3
%uasm_exe% drv_asm.asm
4
5
rem Microsoft Masm VS2010,VS2017,VS2019,...
6
rem call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat"
7
rem ml.exe /c /omf drv_asm.asm
8
9
rem DigitalMars dmc: https://www.digitalmars.com/download/freecompiler.html
10
rem   Digital Mars C/C++ Compiler Version 8.57: http://ftp.digitalmars.com/Digital_Mars_C++/Patch/dm857c.zip
11
rem   DOS 16 libraries: http://ftp.digitalmars.com/Digital_Mars_C++/Patch/dm850dos.zip
12
set DMC=D:\rev_eng\dmc\dm\bin\dmc.exe
13
rem Parameter: https://www.digitalmars.com/ctg/sc.html
14
%DMC% -mtd -NL -2 -c drv_cpp.cpp
15
rem -mtd = Memory model tiny dos -NL = no standard lib, -2 = only <=286 code, -c = only compile
16
17
rem UniLinker: ftp://ftp.styx.cabel.net/pub/UniLink/ulnb1187.zip (or later)
18
set ulink_exe=D:\rev_eng\unilink\ulnb1185\ulink.exe
19
%ulink_exe% -T16 -Tbi drv_asm.obj drv_cpp.obj, drv.drv, drv.map

nach dem kompilieren kommt diese drv_cpp.obj Datei raus - Auszug aus IDA
1
DGROUP:0000
2
DGROUP:0000 ; Segment type: Group
3
DGROUP:0000 DGROUP group _DATA,CONST,_BSS
4
DGROUP:0000
5
_TEXT:0000 ; ===========================================================================
6
_TEXT:0000
7
_TEXT:0000 ; Segment type: Pure code
8
_TEXT:0000 _TEXT  segment word public 'CODE' use16
9
_TEXT:0000        assume cs:_TEXT
10
_TEXT:0000        assume es:nothing, ss:nothing, ds:DGROUP, fs:nothing, gs:nothing
11
_TEXT:0000
12
_TEXT:0000        public _tsub0
13
_TEXT:0000 _tsub0 proc far
14
_TEXT:0000        mov     ds:word_10020, 20
15
_TEXT:0006        retf
16
_TEXT:0006 _tsub0 endp
17
_TEXT:0006
18
_TEXT:0007        public _tsub1
19
_TEXT:0007 _tsub1 proc far
20
_TEXT:0007        mov     ds:word_10022, 22
21
_TEXT:000D        retf
22
_TEXT:000D _tsub1 endp
23
_TEXT:000D
24
_TEXT:000D ; ------------------------------------------------------------------
25
_TEXT:000E        align 4
26
_TEXT:000E _TEXT  ends
27
_TEXT:000E
28
_DATA:0000 ; ===========================================================================
29
_DATA:0000
30
_DATA:0000 ; Segment type: Pure data
31
_DATA:0000 _DATA           segment word public 'DATA' use16
32
_DATA:0000                 assume cs:_DATA
33
_DATA:0000 word_10020      dw 10                  ; DATA XREF: _tsub0+w
34
_DATA:0002 word_10022      dw 11                  ; DATA XREF: _tsub1+w
35
_DATA:0004                 align 10h
36
_DATA:0004 _DATA           ends
37
_DATA:0004
38
CONST:0010 ; ===========================================================================
39
CONST:0010
40
CONST:0010 ; Segment type: Zero-length
41
CONST:0010 CONST           segment word public 'CONST' use16
42
CONST:0011 CONST           ends
43
CONST:0011
44
_BSS:0020 ; ===========================================================================
45
_BSS:0020
46
_BSS:0020 ; Segment type: Zero-length
47
_BSS:0020 _BSS            segment word public 'BSS' use16
48
_BSS:0020 _BSS            ends

und das fertig Plugin "drv.drv" sieht dann nach dem Linken so aus
1
seg000:0000 ; Segment type: Pure code
2
seg000:0000 seg000 segment byte public 'CODE' use16
3
seg000:0000        assume cs:seg000
4
seg000:0000        assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
5
seg000:0000 ; ------------------------------------------------------------------
6
seg000:0000        jmp     near ptr _tsub0
7
seg000:0003 ; ------------------------------------------------------------------
8
seg000:0003
9
seg000:0003 loc_3:                         
10
seg000:0003        jmp     near ptr _tsub1
11
seg000:0006
12
seg000:0006 _tsub0 proc far                
13
seg000:0006                                
14
seg000:0006        mov     word ptr ds:loc_3+1, 20
15
seg000:000C        retf
16
seg000:000C _tsub0 endp
17
seg000:000C
18
seg000:000D
19
seg000:000D _tsub1 proc far                
20
seg000:000D        mov     word ptr ds:_tsub0, 22
21
seg000:0013        retf
22
seg000:0013 _tsub1 endp
23
seg000:0013
24
seg000:0013 ; ------------------------------------------------------------------
25
seg000:0014        dw 10
26
seg000:0016        dw 11
27
seg000:0016 seg000 ends

man sieht deutlich das die Variablen-Offsets so aufgeloest worden sind
als wenn es wirklich ein Daten-Segment geben wuerde, d.h. die Offsets 
reichen in Code-Bereiche

ich habe keine Idee wie ich das lösen kann

von cppbert3 (Gast)


Lesenswert?

Es kommt der gleiche Code raus wenn ich das mit einem alten Borland C++ 
3.1, TLINK, 16 Bit MS-Linker usw. probiere - damit hat es nichts zu tun, 
der Linker hat eben keine Ahnung was er machen soll

von cppbert3 (Gast)


Lesenswert?

die beiden Zuweisungen mit 20 und 22 gehen aus ds:4 und ds:6
1
seg000:0006        mov     word ptr ds:loc_3+1, 20
2
--> mov word ptr ds:4, 20
3
4
seg000:000D        mov     word ptr ds:_tsub0, 22
5
--> mov word ptr ds:6, 22

also mitten rein in meinem Jump-Table-Code, nur warum Offset 4 und 6 ist 
mir noch nicht klar

von cppbert3 (Gast)


Lesenswert?

cppbert3 schrieb:
> also mitten rein in meinem Jump-Table-Code, nur warum Offset 4 und 6 ist
> mir noch nicht klar

ah, ok das Map-File erklaerts

drv.map
1
 Base Offset   Length Name               Class
2
 0000:0000     0006   SEG000             CODE    
3
 0000:0006     000E   _TEXT              CODE    
4
 0001:0004     0004   _DATA              DATA   <-- hier sind die Variablen

d.h. die variablen werden um 0001:0004 => 0001*16+0004 => 14h Bytes nach 
unten verschoben
1
_DATA:0000 ; Segment type: Pure data
2
_DATA:0000 _DATA           segment word public 'DATA' use16
3
_DATA:0000                 assume cs:_DATA
4
_DATA:0000 word_10020      dw 10                  ; DATA XREF: _tsub0+w
5
_DATA:0002 word_10022      dw 11                  ; DATA XREF: _tsub1+w
6
_DATA:0004                 align 10h
7
_DATA:0004 _DATA           ends

word_10020 ist dann bei 14h+0
word_10022 ist dann bei 14h+2

von cppbert3 (Gast)


Lesenswert?

cppbert3 schrieb:
> nur warum Offset 4 und 6 ist
> mir noch nicht klar

und durch das align 4
1
_TEXT:000E        align 4
2
_TEXT:000E _TEXT  ends

werden die Offset um 4 innerhalb der dev_cpp.obj verschoben

von cppbert3 (Gast)


Angehängte Dateien:

Lesenswert?

im Anhang das jetzige Layout mit den falschen Offsets

kann ich überhaupt zum Linkzeitpunkt die falschen mov-Offsets im TEXT 
Segment noch beeinflussen?

eine andere Idee wäre es das DATA-Segment zwischen den Jump-Table und 
die C-Funktionen zu linken und dann irgendwie den Wert von ds per Hand 
über die größe des Tables zu berechnen + Tramplin-Funktion pro 
Table-Eintrag - und damit indirekt die move-Offsets zu korrigieren?

Fühlt sich alles ein wenig bastelig an - aber so ein Plugin ist eben 
auch absolut keine normale Exe oder Com-Program

Kennt jemand vielleicht noch ein Forum das mehr auf solche Frage 
spezialisiert ist?

von cppbert3 (Gast)


Lesenswert?

fast geschafft:

beim UniLink wie auch beim Microsoft Linker gibt es eine Option um 
Sections zu mergen

ich hab jetzt einfach mit "-GM:_TEXT=_DATA" als Linker Parameter 
befohlen die beiden Segmente in eins rein zu machen - und schon passen 
die Offsets

jetzt ist nur noch blöd das der C-Kompiler DS zur Adressierung der Daten 
nutzt - sonst wäre ich schon fertig mit dem Rumpf :(
1
seg000:0000 seg000  segment byte public 'CODE' use16
2
seg000:0000         assume cs:seg000
3
seg000:0000         assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
4
seg000:0000         jmp     near ptr sub_6
5
seg000:0003 ; -------------------------------------------------------------------
6
seg000:0003         jmp     near ptr sub_D
7
seg000:0006
8
seg000:0006 ; ======= S U B R O U T I N E =======================================
9
seg000:0006
10
seg000:0006
11
seg000:0006 sub_6   proc far                ; CODE XREF: seg000:0000j
12
seg000:0006         mov     ds:word_14, 14h
13
seg000:000C         retf
14
seg000:000C sub_6   endp
15
seg000:000C
16
seg000:000D
17
seg000:000D ; ======= S U B R O U T I N E =======================================
18
seg000:000D
19
seg000:000D
20
seg000:000D sub_D   proc far                ; CODE XREF: seg000:0003j
21
seg000:000D         mov     ds:word_16, 16h
22
seg000:0013         retf
23
seg000:0013 sub_D   endp
24
seg000:0013
25
seg000:0013 ; -------------------------------------------------------------------
26
seg000:0014 word_14 dw 0Ah                  ; DATA XREF: sub_6w
27
seg000:0016 word_16 dw 0Bh                  ; DATA XREF: sub_Dw
28
seg000:0016 seg000  ends

von cppbert3 (Gast)


Lesenswert?

jetzt hatte ich gedacht eine schöne Lösung gefunden zu haben (sogar die 
Adressierung per DS sieht so gut aus) - aber leider sind jetzt meine 
Variablen-Offsets wieder falsch :(
1
CALL_C macro c_function
2
  push ds
3
  push cs
4
  pop ds
5
  assume ds:seg000
6
  call c_function
7
  pop ds
8
  retf
9
endm
10
11
extrn _tsub0:near
12
extrn _tsub1:near
13
; extrn _tsub2:near
14
; ...
15
16
seg000 segment byte public 'CODE' USE16
17
  org 0
18
  assume cs:seg000, es:nothing, ss:nothing, ds:nothing
19
20
dummy_entry_point: ; for the linker
21
22
; ---------------------------------------------------------------------------
23
; jump table "interface", far called by the "plugin" loading program
24
  jmp near ptr tsub0_stub
25
  jmp near ptr tsub1_stub
26
  ; jmp near ptr _tsub2
27
  ; ... around 20 function jumps
28
; ---------------------------------------------------------------------------
29
30
tsub0_stub: CALL_C(_tsub0)
31
tsub1_stub: CALL_C(_tsub1)
32
; ...
33
34
seg000 ends
35
36
end dummy_entry_point

von cppbert3 (Gast)


Lesenswert?

Fertig!

so jetzt klappt es - mit dem Open Watcom V2 kann man auch CODE-Segment 
Variablen machen
damit bekomme ich dieses komische Plugin-Konzept unter Kontrolle
und kann jetzt alles schoen in C/C++ nachbauen

drv_asm.asm
1
extrn tsub0_:far
2
extrn tsub1_:far
3
; extrn _tsub2:far
4
; ...
5
6
seg000 segment byte public 'CODE' USE16
7
  org 0
8
  assume cs:seg000, es:nothing, ss:nothing, ds:nothing
9
10
dummy_entry_point: ; for the linker
11
12
; ---------------------------------------------------------------------------
13
; jump table "interface", far called by the "plugin" loading program
14
  jmp near ptr tsub0_stub ; a stubbed version
15
  jmp near ptr tsub1_ ; direct call (if there are no parameters to handle)
16
  ; jmp near ptr _tsub2_stub
17
  ; ... around 20 function jumps
18
; ---------------------------------------------------------------------------
19
20
tsub0_stub: 
21
  ; prepare parameter if needed
22
  jmp near ptr tsub0_
23
24
seg000 ends
25
26
end dummy_entry_point

drv_cpp.cpp
1
#define CODE_SEG_VAR __based( __segname("_CODE") )
2
3
static int CODE_SEG_VAR value1 = 10;
4
static int CODE_SEG_VAR value2 = 11;
5
6
extern "C" {
7
  void far tsub0()
8
  {
9
    value1 = 20;
10
  }
11
  
12
  void far tsub1()
13
  {
14
    value2 = 22;
15
  }
16
}

build
1
D:\rev_eng\uasm249_x64\uasm64.exe drv_asm.asm
2
D:\rev_eng\open-watcom-2_0-c-win-x64\binnt64\wpp.exe drv_cpp.cpp -2 -zl -zls -s
3
D:\rev_eng\ulnb1187\ulink.exe -T16 -Tbi drv_asm.obj drv_cpp.obj, drv.drv, drv.map

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.