Скомпилировать и запустить программу без main() в C


Я пытаюсь скомпилировать и запустить следующую программу без

2 73

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__ и фактически он предполагает, что все, что есть в стеке на что(__end__) местоположение-это обратный адрес, но, к сожалению, его нет, и поэтому он падает.