C Startup Code für 386 schreiben ?
-
das ist meine frage egal ob links tips bin alles dankbar...
cu....
-
Was genau soll der code machen?
Sry, aber unter einem "C Startup Code für 386" kann ich mir ehrlichgesagt nichts gescheites vorstellen.
-
Wenn du ein C file Compilieren wilst mus du diesen .obj file mit dem Startup Code Linken sondern weiss er nicht ist es für window dos ...
mehr will ich auch wiessen !!
-
hmmm ... Du kannst Dir mal den StartUp-Code des CC386 anschauen. Das ist ein Open-Source ANSI-C Compiler. Der Assemblercode liegt bei....
-
Also wenns um den Startup-Code geht..der tut soweit ich weiß nur die dazugehörige Runtime-Library initialisieren, ergo machts nur Sinn sowas zu schreiben, wenn man ne RTL baut und dann hängt der Code massiv davon ab, wie die RTL aufgebaut ist
-
Der Startup-Code sorgt auch dafür, dass in einem C-Programm die main() Funktion aufgerufen wird. Ergo: Jedes C Programm braucht einen Startup-Code.
Beim den Borland Compilern kann man z.B. mit "#pragma exit <p>" und "#pragma startup <p>" die Rotinen festlegen, die beim Starten/Beenden eines Programmes vor bzw. nach main() aufgerufen werden sollen. Der Parameter p gibt hierbei die Priorität an. Für die RTL sind die Werte 0 bis 63 reserviert.
-
Original erstellt von mady:
**Der Startup-Code sorgt auch dafür, dass in einem C-Programm die main() Funktion aufgerufen wird. Ergo: Jedes C Programm braucht einen Startup-Code.
**Also ich kann em Compiler auch sagen, dass di emain-funktion der Entry-Point ist wenn ich mich nicht irre und schon hat sich das mitm Starttup-Code erledigt...nur muss man dann halt darauf achten, dass man argv und argc vermutlich net mehr so zugeworfen bekommt
Aber solange man eine int main(void) hat, ist das kein Problem
-
Original erstellt von TriPhoenix:
Also ich kann em Compiler auch sagen, dass di emain-funktion der Entry-Point ist wenn ich mich nicht irre und schon hat sich das mitm Starttup-Code erledigt...nur muss man dann halt darauf achten, dass man argv und argc vermutlich net mehr so zugeworfen bekommtAber solange man eine int main(void) hat, ist das kein Problem
Und wer initialisiert dann die RTL ?? Und wer sorgt dann für die korekte Rückgabe des Ergebinses der main() an das OS ?? hmmm ...
-
Das muss man natürlich selber machen, hab ich ja auch net anders behauptet. Nur ist es NICHT so, dass man einen Startup-Code braucht um ein C-Programm laufen zu lassen. Und falls man überhuapt keine RTL nutzt und der Rückgabewert ans OS sowieso wurst ist (wie eigenltich oft), kann man den startup-code auch mal sparen. Oder wenn man nicht die ganze RTL mit sich schleppen will, sondern nur ein paar fetzen davon braucht, die man schnell selber gemacht hat, kann man sich die auch sparen.
-
Zumindest braucht *Dein* Programm, welches *ohne* Startup-Code auskommt, als erste ASM-Anweisung einen
call _DEINEMAIN
Das musst Du dann selber schreiben und zu Deinem Progy linken, weil dieser Code sicherlich von keinem Compiler erzeugt wird. Für mich sicht dass dann aber schon wieder nach einem *minimalem* Startup-Code aus .....
Wie auch immer -- eine Diskussion ob oder ob nicht "Startcode notwendig" ist hier OT -- es ging ja nur darum, wie man sowas schreibt ....
-
Original erstellt von mady:
[QB]Zumindest braucht *Dein* Programm, welches *ohne* Startup-Code auskommt, als erste ASM-Anweisung einencall _DEINEMAIN
[QB]Also ich finde nicht dass die Diskussion OT ist
Nicht einmal sowas brauche ich als Startupcode, denn...
...wenn irgendwo Startup-Code vorhanden ist, ob nun von einer RTL oder wenn man ihn selber schreibt, braucht der Compiler einen Entry-Point, d.h. die Stelle wo er anfangen soll. Sei mein Entry-Ppoint nun eine Funktion namens _Entry. Schön dann sage ich dem compiler er soll doch bitte bei _Entry anfangen. Nun nenn mir aber doch mal einen Grund, warum ich dem Compiler nicht direkt meine main als Entry-Point geben soll
Das OS erzeugt beim starten des Programms nunmal einen neuen Prozess mit dem Abbild der Programmdatei und setzt den Instruction Pointer irgendwohin. Ob das nun ein Startupcode ist oder gleich meine Main, das ist dem OS ganz egal.
-
Weil Du damit z.B. gegen den geltenden C Standard verstößt. Deine Programme wären dann sofort nicht mehr portabel.
Wie auch immer. Du kannst mich nur schwer davon überzeugen, dass man absolut keinen Startup-Code benötigt. Ein C-Programm ist in Segmente unterteilt - mindestens Datensegment und Codesegment sind vorhanden. Nach meiner Compiler-Doku (genaugenommen ist es die Doku zum Linker) ordnet der Startup-Code u.a. diese Segmente im Speicher an.
Wenn ich com-Dateien erstelle, die im Speicher exakt genauso aussehen, wie auf der Platte, dann mag das schon funktionieren. Bei komplexeren, ausführbaren Dateien kommt man ohne Startup-Code nicht rum.
-
Original erstellt von mady:
**Weil Du damit z.B. gegen den geltenden C Standard verstößt. Deine Programme wären dann sofort nicht mehr portabel.
**Jedes Programm das Startup-Code verwendet und spätestens jedes Kompilat (und nur das ist es letzendlich was keinen Startup-Code mehr hat) ist nicht Portabel weil Startupcode aufm OS basiert und Kompilate aufm Prozessor und aufm OS.
**
Wie auch immer. Du kannst mich nur schwer davon überzeugen, dass man absolut keinen Startup-Code benötigt. Ein C-Programm ist in Segmente unterteilt - mindestens Datensegment und Codesegment sind vorhanden. Nach meiner Compiler-Doku (genaugenommen ist es die Doku zum Linker) ordnet der Startup-Code u.a. diese Segmente im Speicher an.**Also bei mir macht das immer mein Betriebssystem, das hat nämlich nen dafür vorhandenen Loader der den Adressraum aufbaut, das Binary in den Prozessraum reinmappt, eventuelle Librarys dazumappt, allen Blöcken die passenden Rechte gibt und dann startet.
Ich habe noch extra mal im Startup-Code nachgeguckt, den einige COmpiler gleich als C-Source mitliefern, da passiert nichts mit Segmente, was im Übrigen auch garnicht Möglich ist, da Programme immer im User-Modus laufen und der hat direkt am Speicher nichts verloren.**
Wenn ich com-Dateien erstelle, die im Speicher exakt genauso aussehen, wie auf der Platte, dann mag das schon funktionieren. Bei komplexeren, ausführbaren Dateien kommt man ohne Startup-Code nicht rum.**Das war eine Herausforderung
Das Beispiel ist natürlich klein, aber wenn man will, kann man da natürlich auch größere Apps drauf bauen
#include <windows.h> void main(void) { HANDLE hCon = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); WriteConsole(hCon, "Hello, World!\n", 14, NULL, NULL); TerminateProcess(GetCurrentProcess(), 0); }
zu kompilieren auf M$-Compiler per
cl NoStartup.cpp /link kernel32.lib /nologo /entry:"main"
Ausgabe:
X:\Developing\NoStartup>NoStartup.exe Hello, World!
Und hier noch eine Disassemblierung um die letzten Zweifel zu beseitigen ;):
00401000 >/$ 55 PUSH EBP 00401001 |. 8BEC MOV EBP, ESP 00401003 |. 51 PUSH ECX 00401004 |. 6A 00 PUSH 0 ; /hTemplateFile = NULL 00401006 |. 6A 00 PUSH 0 ; |Attributes = 0 00401008 |. 6A 03 PUSH 3 ; |Mode = OPEN_EXISTING 0040100A |. 6A 00 PUSH 0 ; |pSecurity = NULL 0040100C |. 6A 03 PUSH 3 ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE 0040100E |. 68 00000040 PUSH 40000000 ; |Access = GENERIC_WRITE 00401013 |. 68 00304000 PUSH NoStartu.00403000 ; |FileName = "CONOUT$" 00401018 |. FF15 08204000 CALL [<&KERNEL32.CreateFileA>] ; \CreateFileA 0040101E |. 8945 FC MOV [EBP-4], EAX 00401021 |. 6A 00 PUSH 0 ; /pReserved = NULL 00401023 |. 6A 00 PUSH 0 ; |pWritten = NULL 00401025 |. 6A 0E PUSH E ; |CharsToWrite = E (14.) 00401027 |. 68 08304000 PUSH NoStartu.00403008 ; |Buffer = NoStartu.00403008 0040102C |. 8B45 FC MOV EAX, [EBP-4] ; | 0040102F |. 50 PUSH EAX ; |hConsole = NULL 00401030 |. FF15 04204000 CALL [<&KERNEL32.WriteConsoleA>] ; \WriteConsoleA 00401036 |. 6A 00 PUSH 0 ; /ExitCode = 0 00401038 |. FF15 00204000 CALL [<&KERNEL32.GetCurrentProcess>] ; |[GetCurrentProcess 0040103E |. 50 PUSH EAX ; |hProcess = NULL 0040103F |. FF15 0C204000 CALL [<&KERNEL32.TerminateProcess>] ; \TerminateProcess 00401045 |. 8BE5 MOV ESP, EBP 00401047 |. 5D POP EBP 00401048 \. C3 RETN
Bzw. für Hexadezimalfreunde:
X:\Developing\NoStartup>od -x NoStartup.exe 0000000 5a4d 0090 0003 0000 0004 0000 ffff 0000 0000020 00b8 0000 0000 0000 0040 0000 0000 0000 0000040 0000 0000 0000 0000 0000 0000 0000 0000 0000060 0000 0000 0000 0000 0000 0000 00c8 0000 0000100 1f0e 0eba b400 cd09 b821 4c01 21cd 6854 0000120 7369 7020 6f72 7267 6d61 6320 6e61 6f6e 0000140 2074 6562 7220 6e75 6920 206e 4f44 2053 0000160 6f6d 6564 0d2e 0a0d 0024 0000 0000 0000 0000200 0e45 da60 6f01 890e 6f01 890e 6f01 890e 0000220 6f01 890f 6f05 890e 7063 891d 6f02 890e 0000240 70e9 8905 6f00 890e 6952 6863 6f01 890e 0000260 0000 0000 0000 0000 0000 0000 0000 0000 0000300 0000 0000 0000 0000 4550 0000 014c 0003 0000320 1a38 3d6a 0000 0000 0000 0000 00e0 010f 0000340 010b 0006 1000 0000 2000 0000 0000 0000 0000360 1000 0000 1000 0000 2000 0000 0000 0040 0000400 1000 0000 1000 0000 0004 0000 0000 0000 0000420 0004 0000 0000 0000 4000 0000 1000 0000 0000440 0000 0000 0003 0000 0000 0010 1000 0000 0000460 0000 0010 1000 0000 0000 0000 0010 0000 0000500 0000 0000 0000 0000 2014 0000 0028 0000 0000520 0000 0000 0000 0000 0000 0000 0000 0000 * 0000640 2000 0000 0014 0000 0000 0000 0000 0000 0000660 0000 0000 0000 0000 0000 0000 0000 0000 0000700 742e 7865 0074 0000 0049 0000 1000 0000 0000720 1000 0000 1000 0000 0000 0000 0000 0000 0000740 0000 0000 0020 6000 722e 6164 6174 0000 0000760 00a4 0000 2000 0000 1000 0000 2000 0000 0001000 0000 0000 0000 0000 0000 0000 0040 4000 0001020 642e 7461 0061 0000 0017 0000 3000 0000 0001040 1000 0000 3000 0000 0000 0000 0000 0000 0001060 0000 0000 0040 c000 0000 0000 0000 0000 0001100 0000 0000 0000 0000 0000 0000 0000 0000 * 0010000 8b55 51ec 006a 006a 036a 006a 036a 0068 0010020 0000 6840 3000 0040 15ff 2008 0040 4589 0010040 6afc 6a00 6a00 680e 3008 0040 458b 50fc 0010060 15ff 2004 0040 006a 15ff 2000 0040 ff50 0010100 0c15 4020 8b00 5de5 00c3 0000 0000 0000 0010120 0000 0000 0000 0000 0000 0000 0000 0000 * 0020000 2064 0000 2078 0000 2088 0000 2050 0000 0020020 0000 0000 203c 0000 0000 0000 0000 0000 0020040 2096 0000 2000 0000 0000 0000 0000 0000 0020060 0000 0000 0000 0000 0000 0000 2064 0000 0020100 2078 0000 2088 0000 2050 0000 0000 0000 0020120 029e 6554 6d72 6e69 7461 5065 6f72 6563 0020140 7373 0000 00f7 6547 4374 7275 6572 746e 0020160 7250 636f 7365 0073 02d4 7257 7469 4365 0020200 6e6f 6f73 656c 0041 0034 7243 6165 6574 0020220 6946 656c 0041 454b 4e52 4c45 3233 642e 0020240 6c6c 0000 0000 0000 0000 0000 0000 0000 0020260 0000 0000 0000 0000 0000 0000 0000 0000 * 0030000 4f43 4f4e 5455 0024 6548 6c6c 2c6f 5720 0030020 726f 646c 0a21 0000 0000 0000 0000 0000 0030040 0000 0000 0000 0000 0000 0000 0000 0000 * 0040000
Kein Startup-Code
[ Dieser Beitrag wurde am 26.08.2002 um 14:15 Uhr von TriPhoenix editiert. ]
-
hmmmm - na schön; ich geb' mich geschlagen - dieses mal! *gg*
ich hab' hier grad keinen VC++ um das testen zu können. Aber ich denke nicht, dass das mit jedem Compiler funktioniert ....
-
Original erstellt von mady:
ich hab' hier grad keinen VC++ um das testen zu können. Aber ich denke nicht, dass das mit jedem Compiler funktioniert ....Also bei gcc gibts -nostartfiles -nostandardlibs -nodefaultlibs
Hab aber noch keine option gefunden, um den Entry-Point direkt anzugeben, ich schätze gcc nimmt dann einfach main