У main есть обратный адрес, динамическая ссылка или возвращаемое значение в C?
Согласно нашей книге, каждая функция имеет запись активации в стеке времени выполнения в C. Каждая из этих записей активации имеет адрес возврата, динамическую ссылку и возвращаемое значение. У главного тоже есть?
4 ответа
Все эти термины являются чисто деталями реализации - C не имеет понятия "обратные адреса" или "динамические ссылки". У него даже нет понятия "стек" вообще. В большинстве реализаций C есть эти объекты, и в этих реализациях возможно, что они существуют для main
, Однако не требуется, чтобы это произошло.
Надеюсь это поможет!
Если вы разберете функции, вы поймете, что большую часть времени в стеке даже нет возвращаемого значения - часто это происходит в регистре EAX (intel x86). Вы также можете посмотреть "соглашения о вызовах" - все зависит от компилятора. C - это язык, то, как он интерпретируется в машинный код, это не "его" дело.
Хотя это зависит от реализации, стоит взглянуть на программу на C, скомпилированную с помощью gcc. Если вы бежите objdump -d executable
, вы увидите, что он разобран, и вы можете увидеть, как main()
ведет себя. Вот пример:
08048680 <_start>:
...
8048689: 54 push %esp
804868a: 52 push %edx
804868b: 68 a0 8b 04 08 push $0x8048ba0
8048690: 68 30 8b 04 08 push $0x8048b30
8048695: 51 push %ecx
8048696: 56 push %esi
8048697: 68 f1 88 04 08 push $0x80488f1
804869c: e8 9f ff ff ff call 8048640 <__libc_start_main@plt>
80486a1: f4 hlt
...
080488f1 <main>:
80488f1: 55 push %ebp
80488f2: 89 e5 mov %esp,%ebp
80488f4: 57 push %edi
80488f5: 56 push %esi
80488f6: 53 push %ebx
...
8048b2b: 5b pop %ebx
8048b2c: 5e pop %esi
8048b2d: 5f pop %edi
8048b2e: 5d pop %ebp
8048b2f: c3 ret
Вы можете видеть, что main ведет себя подобно обычной функции в том, что она возвращает нормально. На самом деле, если вы посмотрите на базовую документацию Linux, вы увидите, что вызов __libc_start_main
что мы видим из _start
на самом деле требует main
вести себя как обычная функция.
В C/C++ main()
написан так же, как функция, но не один. Например, нельзя звонить main()
, у него есть несколько возможных прототипов (не может сделать это в C!). Что бы ни было return
Редактируемый файл передается операционной системе (и программа завершается).
Отдельные реализации C могут обрабатывать main()
как функция, вызываемая извне для единообразия, но никто не заставляет их делать это (или запрещает переключаться на какую-либо другую форму, не сообщая об этом никому). Существуют традиционные способы реализации C, но никто не вынужден делать это таким образом. Это просто самый простой способ для наших типичных архитектур.