Скомпилировать и запустить программу без main() в C
Я пытаюсь скомпилировать и запустить следующую программу без
2 ответа:
давайте посмотрим на сгенерированный сборка программы:
.LC0: .string "Hello World..." .LC1: .string "Successfully run without main..." nomain: push rbp mov rbp, rsp mov edi, OFFSET FLAT:.LC0 call puts mov edi, OFFSET FLAT:.LC1 call puts nop pop rbp ret
Примечание
ret
заявление. Точка входа в вашу программу определяется какnomain
, все в порядке с этим. Но как только функция возвращается, она пытается перейти в адрес в стеке вызовов... это не заселено. Это незаконный доступ и ошибка сегментации следует.быстрое решение было бы позвонить
exit()
в конце вашей программы (и предполагая, что C11 мы могли бы также отметить функцию как_Noreturn
):#include <stdio.h> #include <stdlib.h> _Noreturn void nomain(void) { printf("Hello World...\n"); printf("Successfully run without main...\n"); exit(0); }
в самом деле, теперь ваша функция ведет себя почти как обычный
main
функция, так как после возвращения изmain
на Сmain
возвращаемое значение.
В C, когда функции/подпрограммы называются стек заполняется как (в порядке):
- доводы
- обратный адрес,
- локальные переменные, --> верхняя часть стека
main () будучи начальной точкой, ELF структурирует программу таким образом, что любые инструкции, которые приходят первыми, будут нажаты первыми, в этом случае printfs.
теперь программа как бы усечена без обратный адрес или
__end__
и фактически он предполагает, что все, что есть в стеке на что(__end__
) местоположение-это обратный адрес, но, к сожалению, его нет, и поэтому он падает.