„Hello world” w C bez użycia biblioteki standardowej

02.01.2013 Notatki CstdlibAsembler

Wspomniany post znajduje się tutaj.

Pozwoliłem sobie jednak zmienić trochę założenia „ćwiczenia” i pozwolić na użycie __asm__. Moje rozwiązanie jest nieprzenośne (działa tylko pod Linuksem) i wymaga skorzystania z rozszerzenia kompilatora którego nie ma w dokumentacji języka, ale pozwala szybciej zrozumieć zasadę działania kodu.

#define NULL 0

#define SYS_exit    0x01
#define SYS_write   0x04

#define STDOUT_fd 1

int syscall(unsigned int id, unsigned int arg1, unsigned int arg2, unsigned int arg3, unsigned int arg4, unsigned int arg5){
    int ret = 0;
    __asm__ ("movl %1, %%eax;"
             "movl %2, %%ebx;"
             "movl %3, %%ecx;"
             "movl %4, %%edx;"
             "movl %5, %%esi;"
             "movl %6, %%edi;"
             "int $0x80;"
             : "=r" ( ret )
             : "r" ( id ), "r" (arg1), "r" (arg2), "r" (arg3), "r" (arg4), "r" (arg5)
             : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
             );
    return ret;
}

inline void exit(int code){
    syscall(SYS_exit, code, NULL, NULL, NULL, NULL);
}

void write(char *buf){
    char *start=buf;
    while(*(buf++)!=0){}
    syscall(SYS_write, STDOUT_fd, start, buf-start, NULL, NULL);
}

_start(){
    write("Hello world\n");
    exit(0);
}