yuezonghe | 824eb0c | 2024-06-27 02:32:26 -0700 | [diff] [blame^] | 1 | /* |
| 2 | * June 27, 2001 Manuel Novoa III |
| 3 | * |
| 4 | * This is a heavily modified version of gcc's output for the _syscall5 macro. |
| 5 | * The idea (originally from dietlibc) is that all syscall functions simply set |
| 6 | * the syscall number as the first argument, then set the syscall arguments as |
| 7 | * the next up-to-five arguments, and then jump here. All the common work is |
| 8 | * done by syscall(), saving a fair amount of generated code when a number of |
| 9 | * syscalls are used. The (potential) cost is some unnecessary pushes, pops, |
| 10 | * and movs but the execution time penalty should be relatively small compared |
| 11 | * to the cost of the syscall itself. |
| 12 | * |
| 13 | * July 24, 2002 |
| 14 | * |
| 15 | * Modified by Erik Andersen to take all function parameters from off the stack |
| 16 | * like a proper function and eliminates the old 255 syscall number limit. So |
| 17 | * now we can just call this as a function as syscall() per the function |
| 18 | * prototype in unistd.h, so to call _exit(42) you can just call. |
| 19 | * syscall(__NR_exit, 42); |
| 20 | * and things will just work. |
| 21 | */ |
| 22 | |
| 23 | .text |
| 24 | .global syscall |
| 25 | .type syscall,%function |
| 26 | syscall: |
| 27 | pushl %ebp |
| 28 | pushl %edi |
| 29 | pushl %esi |
| 30 | pushl %ebx |
| 31 | |
| 32 | movl 44(%esp),%ebp /* Load the 6 syscall argument registers */ |
| 33 | movl 40(%esp),%edi |
| 34 | movl 36(%esp),%esi |
| 35 | movl 32(%esp),%edx |
| 36 | movl 28(%esp),%ecx |
| 37 | movl 24(%esp),%ebx |
| 38 | movl 20(%esp),%eax /* Load syscall number into %eax. */ |
| 39 | int $0x80 |
| 40 | |
| 41 | popl %ebx |
| 42 | popl %esi |
| 43 | popl %edi |
| 44 | popl %ebp |
| 45 | |
| 46 | cmpl $-4095,%eax |
| 47 | jae __syscall_error |
| 48 | ret /* Return to caller. */ |
| 49 | |
| 50 | .size syscall,.-syscall |