Я хочу написать "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
#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
Комментариев нет:
Отправить комментарий