2008-08-15 46 views

Odpowiedz

25

plik .exe (lub równowartość w innych platformach) zawiera „punkt wejścia ' adres. Do pierwszego przybliżenia system operacyjny ładuje odpowiednie partycje pliku .EXE do pamięci RAM, a następnie przeskakuje do punktu wejścia.

Jak już powiedzieli inni, ten punkt wejścia nie będzie "głównym", ale zamiast tego będzie częścią biblioteki uruchomieniowej - będzie robił takie rzeczy jak inicjowanie obiektów statycznych, ustawianie parametrów argc/argv, konfigurowanie stdin/stdout/stderr, itd. Kiedy to wszystko zrobi, wywoła funkcję your main(). Podczas głównych wyjść środowisko wykonawcze przechodzi przez proces przetwarzania kodu zwrotnego z powrotem do środowiska, wywoływanie statycznych destruktorów, wywoływanie procedur _atexit itp.

Jeśli masz narzędzia MS (być może nie te z freebie), to mieć całe środowisko uruchomieniowe, a łatwym sposobem na sprawdzenie tego jest umieszczenie punktu przerwania w nawiasie klamrowym metody main() i pojedynczy krok z powrotem w środowisku wykonawczym.

8

main() jest częścią biblioteki C i nie jest funkcją systemową. Nie wiem o OS X ani Linuxie, ale Windows zwykle uruchamia program z WinMainCRTStartup(). Ten symbol rozpoczyna proces, usuwa argumenty wiersza poleceń i środowisko (argc, argv, end) i wywołuje main(). Jest również odpowiedzialny za wywoływanie dowolnego kodu, który powinien działać po main(), jak atexit().

Patrząc w pliku Visual Studio, powinieneś być w stanie znaleźć domyślną implementację WinMainCRTStartup, aby zobaczyć, co robi.

Można również zdefiniować własną funkcję wywołania przy uruchomieniu, odbywa się to poprzez zmianę "punktu wejścia" w opcjach linkera. Często jest to funkcja, która nie przyjmuje argumentów i zwraca pustkę.

1

Expert C++/CLI (sprawdź na stronie 279) zawiera szczegółowe informacje na temat różnych scenariuszy ładowania początkowego dla natywnych, mieszanych i czystych zespołów CLR.

1

Jest zależny od systemu operacyjnego. W OS X, w nagłówku machu znajduje się ramka zawierająca adres początkowy rejestru EIP (wskaźnik instrukcji).

Po binarny jest załadowany, system operacyjny uruchamia wykonanie z tego adresu:

 
cristi:test diciu$ otool -l ./a.out | grep -A 10 LC_UNIXTHREAD 
     cmd LC_UNIXTHREAD 
    cmdsize 80 
    flavor i386_THREAD_STATE 
     count i386_THREAD_STATE_COUNT 
[..] 
     ss 0x00000000 eflags 0x00000000 eip 0x00001f8c cs 0x00000000 
[..] 

adres jest adresem funkcji "start" z binarnym:

 
cristi:test diciu$ nm ./a.out 
0000200c D _NXArgc 
00002008 D _NXArgv 
00002000 D ___progname 
00001fe0 t __dyld_func_lookup 
00001000 A __mh_execute_header 
[..] 
00001f8c T start 

W systemie Mac OS X, jest to funkcja "startowa", która jest wywoływana jako pierwsza, nawet przed "główną" funkcją:

 
(gdb) b start 
Breakpoint 1 at 0x1f90 
(gdb) b main 
Breakpoint 2 at 0x1ff4 
(gdb) r 
Starting program: /Users/diciu/Programming/test/a.out 
Reading symbols for shared libraries ++. done 

Breakpoint 1, 0x00001f90 in start() 
5

O ile w indows idzie, funkcje punktu wejścia są:

  • konsoli: void __cdecl mainCRTStartup(void) {}
  • GUI: void __stdcall WinMainCRTStartup(void) {}
  • DLL: BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL,DWORD fdwReason,void* lpReserved) {}

Jedynym powodem, aby z nich korzystać na normalną main/WinMain/DllMain jest jeśli chcesz użyć własnej biblioteki czasu wykonywania (jeśli chcesz zmniejszyć rozmiar pliku lub niestandardowe funkcje)

Dla niestandardowego czasu wykonywania implementat jony i inne sztuczki, aby uzyskać mniejsze pliki PE, patrz:

0

Jeżeli są Państwo zainteresowani w książce związanej z Windows i Win32 API spróbuj

"Programowanie aplikacji dla Mi crosoft Windows "autorstwa Jeffreya Richtera.