Compilter Frage...



  • Hallo,
    ich lese gerade etwas Über Compiler.

    int WINAPT WinMain ( |
    HINSTANCE hinstance, 	  
    HINSTANCK hPrevinetance, 
    LPSTR lpCMDLine,		
    int nCMDShow 		  
    );
    
    

    1.Frage:
    Der Code soll der Start Code sein von jedem CPP Programm, ich dachte immer main(). Wie verstehe ich das?
    2.Frage:
    Ist das eine bestimmte Art von CPP ? Es gibt ja MFC, CLI, Commandoline...
    3.Frage:
    Ist der Satz so richtig(meine eigene Worte)?
    Windows b.z.w. der Kernel holt sich in Verbindung mit GetModuleHandleA das fertige CPP Programm und steckt den Code von Festplatte in den Artbeitsspeicher.

    .text:00401804 push eax
    .text:00401805 push esi
    .text:00401806 push ebx
    .text:00401807 push ebx
    .text:00401808 call ds : GetModuleHandleA
    .text:0040180E push eax
    .text:0040180F call §WinMain@16
    .text:00401814 mov [ebpt+var 68], eax
    .text:00401817 push eax
    .text:00401818 call ds:exit
    
    


    1. Das ist eine Eigenheit der Windows-Programmierung. Windows-Programme benutzen WinMainals Einsprungsfunktion, und nicht main wie vom c++ Standard vorgesehen.

    2. C++ ist C++, es gibt Bibliotheken/Frameworks, die in C/C++ geschrieben sind und bestimmte Funktionen anbieten. Prinzipiell können mit C/C++ alle Frameworks benutzt werden, die sich an bestimme Aufrufkonventionen halten. C ist da unkritischer als C++. Windows Programme benutzen in der einen oder anderen Form fast immer das WINAPI SDK, sei es nativ (C/C++) oder als Wrapper (Teile des .net Frameworks). Daher ist "MFC-C++" keine anderes C++, sondern Standard C++, das das MFC Framework benutzt. CLI ist was anderes, da Microsoft einen C++ Dialekt mit eigenen Schlüsselwörtern geschaffen hat. Was du mit "Commandoline" meinst weiß ich nicht.

    3. Das ist etwas komplizierter als "der Kernel holt sich das fertige C++ Programm und steckt den Code von der Festplatte in den Arbeitsspeicher". Zunächst ist das "fertige C++ Programm" ein Executable in einem bestimmten Format (PE-Format), das der zugrunde liegende Quelltext C++ war lässt sich am Executable nicht mehr feststellen.
      aber zunächst lädt Windows die Programmdatei (und ggf. weitere DLLs) in einen privaten Adressbereich, den Windows für den neuen Prozess vorbereitet hat. Anschließend bereitet die C-Runtime (CRT) die Umgebung für den Prozess vor und ruft nach allen Vorbereitungen main()/WinMain mit den entsprechenden Parametern auf.

    Hier gibt´s deutlich mehr Informationen darüber, wie Windows ein Executable lädt und ausführt. Insbesondere der "PE Resources" Abschnitt hat weitere nützliche Links.



  • thx,
    mit Commandoline meine ist die DosBox.
    Stimmt das so?

    Anders ausgedrückt, Der Compilter macht aus Textblock 1 einen Textblock 2.
    Textblock 1 ist der Prototype, weil ich in CPP mit main() arebeite.
    Wenn ich die Exe Datei mit dem Disasembler anschaue, sehe ich Textblock 2.



  • @tomycat2009 sagte in Compilter Frage...:

    ...
    mit Commandoline meine ist die DosBox.
    Stimmt das so?
    ...

    Ich weiß nicht, ob du mit Commandoline DosBox meinst, das kannst nur du beantworten. Meinst du vielleicht eine Konsolenanwendung? DoxBox ist jedenfalls ein x86 Emulator, der uraltes MS-DOS emuliert.

    Anders ausgedrückt, Der Compilter macht aus Textblock 1 einen Textblock 2.
    Textblock 1 ist der Prototype, weil ich in CPP mit main() arebeite.
    Wenn ich die Exe Datei mit dem Disasembler anschaue, sehe ich Textblock 2.

    Nö, das sind Debug Informationen, die der Compiler zusammen mit dem Programm erzeugt. Diese Informationen sind nur im Debug-Build vorhanden, im Release Build gibts es keine benannten Objekte mehr, die man sich im Speicher angucken könnte.

    Edit:
    Der Compiler macht auch nicht aus einem Textblock 1 einen Textblock 2. Der Compiler übersetzt Programmquelltext in Binärcode und der Disassembler macht daraus wieder was lesbares.



  • @DocShoe
    Najaaaaaaa...
    Also je nach Compiler funktioniert das schon genau so, dass der Compiler aus einem Textblock einen neuen, anderen Textblock macht. Der neue Textblock wird dann in den Assembler hineingefüttert, wobei dann ein Objectfile rausfällt. AFAIK arbeitet GCC intern immer noch so.

    Das was man im Debugger sieht ist allerdigns normalerweise trotzdem disassembliert und nicht der originale Assembler-Source den der Compiler erzeugt hat.



  • Danke Jungs,
    Mein Wissensstand:
    Über viele Jahre Nutze ich Visual C#/C++
    Debugmodus zum testen und Release Produkt ist für mein Kunde.

    Ok, jezt nochmal zum Verständnis.
    Ich progge eine Hallo Welt App in C++ Anwendung.
    Nach dem compilieren wird aus main eine winmain.
    Dann starte ich den Debugger und öffne die exe Datei.
    Anstelle von Winmain finde ich Textblock II.
    Ist mein Gedankengang richtig?

    2.ten Was ist dann der Textblock I ? In welche Schublade kann ich den Sinngemäs zuordnen?



  • @hustbaer
    Stimmt, den Assembler hatte ich überhaupt nicht mehr auf dem Schirm. Ich habe den ganzen Übersetzungsprozess in zwei Schritte eingeteilt: Übersetzen und Linken. Dass das Übersetzen in mehreren Schritten passiert habe ich nicht erwähnt, weil ich das, was intern passiert und nur Zwischenprodukte erzeugt/benutzt, für nicht relevant halte, zumindest in diesem Thread.

    @tomycat2009
    Du hast da sehr, sehr naive Ansichten. Nach dem Kompilieren wird aus WinMain nicht main, nach dem Kompilieren ist eine Funktion nur noch eine Adresse, sie hat nicht einmal mehr ihren Namen.
    Jede Windows Anwendung hat einen, ich nenn´s mal "Starter-Stub", der die Umgebung für den zu startenden Prozess vorbereitet. Je nach Projekttyp gibt´s da unterschiedliche Stubs, die unterschiedliche Einsprungsfunktionen haben. Deshalb ist es bei Windowsprogrammen WinMain und bei Standard-C++ Programmen halt main. Der Compiler macht aus einer Funktion keine andere (macht ja auch keinen Sinn, weil eine Funktion nach dem Kompilieren ja eh nur noch eine Adresse ist).

    Ich weiß auch nicht, warum du ständig von Textblöcken redest... das Einzige, das als echter Text vorliegt, ist der Quelltext. Der taucht im Executable aber nicht mehr auf, man kann aus einem C++ Executable den Quelltext nicht mehr rekonstruieren. Das, was du im Debugger siehst, sind Debug Informationen, die zusätzlich zum Binärcode vom Compiler erzeugt werden, und auch nur dann, wenn man dem Compiler sagt, dass er das tun soll (Debug-Build). Debug Builds sind häufig größer und langsamer als der Release-Build, deshalb benutzt man den Debug-Build zum Testen und Bugfixing, der Release-Build ist dann das, was man auf die Welt loslässt.
    Das, was du als "Textblock II" bezeichnest, ist das, was der Debugger zusammen mit den Debug Informationen für dich visuell aufbereitet. In Wirklichkeit gibt es diesen "Textblock II" überhaupt nicht, das sucht sich der Debugger/IDE aus dem Binärcode, Quelltext und Debug-Informationen für dich zusammen.


Log in to reply