Страницы

Поиск по вопросам

среда, 5 июня 2019 г.

Как сделать функцию syscall?

Я хочу написать "Hello World" без glibc, для этого мне нужно написать свою маленькую libc, я сделал несколько простых функций которые не требуют системных вызовов, но теперь хочу сделать функцию write чтоб функция puts заработала, но для write нужна функция syscall, а для того чтоб сделать syscall нужно знать Асембрер, а я его совсем не знаю, я всеже рискнул попробовать написать hello world, после долгого гугления и через несколько десятков компиляций, я на экране увидел "Hello World!", в первые пол секунды я не поверил что у меня вышло Гг
__asm__( ".data;" "msg:" ".ascii \"Hello, world!
\";" // Строка для вывода "len = . - msg;" // Записуем в переменную len длину msg );
void _start() {
__asm__( "mov r0, #1;" // Запись в поток #1 - stdout "ldr r1, =msg;" // Указатель на строку "ldr r2, =len;" // Длина строки "mov r7, #4;" // Номер системного вызова - 4 (write) "swi 0;" // Системный вызов ядра );
__asm__( "mov r0, #0;" // Возращаемое значение - 0 "mov r7, #1;" // Номер системного вызова - 1 (exit) "swi 0;" // Системный вызов ядра ); }
Насколько я понял для системного вызова нужно записать в переменную(или это ригистры, я не знаю чем отличается первое от второго) r7 номер вызова, а в переменные r1, r2, r3... передаваемые аргументы, но как написать функцию syscall(номер вызова,Аргументы...) я не знаю, тут нужно либо полностью писать её на Ассемблере, а это я точно не смогу, либо писать на C и передавать аргументы в Ассемблер, это я тоже не умею.
Может кто либо помочь написать функцию syscall для arm?


Ответ

Вот, накидал по-быстрому "Hello World", где системные вызовы осуществляются с помощью ряда функций syscall, для различного количества аргументов N. Можно, конечно, заморочиться, и сделать еще единую функцию с переменным числом аргументов с помощью va_list
#include
#define SYS_EXIT 1 #define SYS_WRITE 4
#define STDIN 0 #define STDOUT 1 #define STDERR 2
size_t strlen(const char *s) { size_t n; for (n = 0; *s; ++n, ++s) ; return n; }
void syscall1(int cnum, int arg1) { __asm__ __volatile__( "mov r0, %0;" "mov r7, %1;" "swi 0;" : : "r"(arg1), "r"(cnum) : "r0", "r7" ); }
void syscall3(int cnum, int arg1, int arg2, int arg3) { __asm__ __volatile__( "mov r0, %0;" "mov r1, %1;" "mov r2, %2;" "mov r7, %3;" "swi 0;" : : "r"(arg1), "r"(arg2), "r"(arg3), "r"(cnum) : "r0", "r1", "r2", "r7" ); }
void _start() { char *msg = "Hello world
";
syscall3(SYS_WRITE, STDOUT, (int)msg, strlen(msg)); syscall1(SYS_EXIT, 0); }
Компиляция и запуск:
$ gcc -nostdlib test.c -o test $ ./test Hello World

Комментариев нет:

Отправить комментарий