Компиляция и запуск программы без 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, когда функции/подпрограммы называются стеком, заполняется как (в порядке):

  1. доводы
  2. обратный адрес,
  3. локальные переменные, --> верхняя часть стека

main () будучи начальной точкой, ELF структурирует программу таким образом, что любые инструкции сначала будут выталкиваться первыми, в этом случае printfs.

теперь программа усечена без обратный адрес или __end__ и infact предполагает, что все, что есть в стеке, при этом (__end__) местоположение является обратным адресом, но, к сожалению, его нет, и, следовательно, он падает.