4

I want to write a tiny standalone executablewithout using libc. what I need for simulating some libc functions is to have function to do syscalls using inline assembly :

int syscall(int a,...) {
return __asm__ volatile (/* DO STH HERE */);
}

I am using Linux and ARM processor.

EDIT: found the solution:

int syscall(int n,...) {
return __asm__ volatile ("mov r7,r0\nmov r0,r1\nmov r1,r2\nmov r2,r3\nswi #1\n");
}
alireza_fn
  • 884
  • 1
  • 8
  • 21
  • not sure, It's about errno in arm syscall but I am asking for a function to do syscall using arm inline assembly. – alireza_fn Feb 12 '14 at 14:29
  • 1
    Are we reading the same question? I don't see anything about errno in that one, but I do see `SVC{}{} {#}` and an explanation of it in the top answer. – Magnus Reftel Feb 12 '14 at 14:45
  • See: [Thumb as `_start`](http://stackoverflow.com/questions/20369440/can-start-be-the-thumb-function); different question with same answers. – artless noise Feb 12 '14 at 18:57

1 Answers1

3

First you need to be able to command your toolchain (gcc?) to not to include anything extra other than your code. Something like -nostartfiles -nodefaultlibs to gcc should work.

Then you need to be nice working with Linux, meaning your elf need to be loaded properly by the os, meaning it needs to have _start point visible. Below would be such an example:

void _start() __attribute__ ((naked));
void _start() {
    main();
    asm volatile(
        "mov r7, #1\n" /* exit */
        "svc #0\n"
    );
}

You can then create a main which contain what you want to do.

int main() {
    linuxc('X');
    return 42;
}

Then doing extra with write syscall...

void linuxc(int c) {
    asm volatile(
        "mov r0, #1\n" /* stdout */
        "mov r1, %[buf]\n" /* write buffer */
        "mov r2, #1\n" /* size */
        "mov r7, #4\n" /* write syscall */
        "svc #0\n"
        : /* output */ : [buf] "r" (&c) : "r0", "r1", "r2", "r7", "memory"
    );
}

I have a more complete example of that at my github. I like the teensy one most.

auselen
  • 27,577
  • 7
  • 73
  • 114
  • thanks for answer but I need a function to do any syscall not only write syscall. also it should use VA_ARGs to avoid some issues. – alireza_fn Feb 12 '14 at 14:53
  • @alireza7991 I don't think that there are any variadic syscalls. It might be very well that my other answer mentioned under comments in your question is much suited as an answer for you (boiler plate code for syscalls with uclib). Check first link for my variadic implementation of printf with no standard libs. – auselen Feb 12 '14 at 15:01
  • so I would need to write a syscall function for every libc function? – alireza_fn Feb 12 '14 at 15:16
  • Is there any way to do this use assembly codes(not inline assembly)? – alireza_fn Feb 12 '14 at 15:17
  • Yes and yes. You just need to start from somewhere. – auselen Feb 12 '14 at 15:52
  • Note that you may obtain more efficient code by using named register variables as shown at: https://stackoverflow.com/questions/3929442/how-to-specify-an-individual-register-as-constraint-in-arm-gcc-inline-assembly/54845046#54845046 – Ciro Santilli Feb 24 '19 at 12:55