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....

    http://www.members.tripod.com/~ladsoft/cc386.htm



  • 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 bekommt 🙂 Aber 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 einen

    call _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


Anmelden zum Antworten