参考:https://github.com/lpsantil/rt0
/* Copyright (c) 2015, Louis P. Santillan
* All rights reserved.
* See LICENSE for licensing details.
*/
#ifndef __RT0_SYSCALL__
#define __RT0_SYSCALL__
#include
#include
#ifdef __LP64__
#include
#else
#include
#endif
long syscall6( long n, long a0, long a1, long a2, long a3, long a4, long a5 );
#ifndef __RT0_WITH_FASTER_SYSCALL__
#define syscall5( m, b0, b1, b2, b3, b4 ) \
syscall6( ( m ), ( b0 ), ( b1 ), ( b2 ), ( b3 ), ( b4 ), 0 )
#define syscall4( m, b0, b1, b2, b3 ) \
syscall5( ( m ), ( b0 ), ( b1 ), ( b2 ), ( b3 ), 0 )
#define syscall3( m, b0, b1, b2 ) \
syscall4( ( m ), ( b0 ), ( b1 ), ( b2 ), 0 )
#define syscall2( m, b0, b1 ) \
syscall3( ( m ), ( b0 ), ( b1 ), 0 )
#define syscall1( m, b0 ) \
syscall2( ( m ), ( b0 ), 0 )
#define syscall0( m ) \
syscall1( ( m ), 0 )
#else
long syscall5( long n, long a0, long a1, long a2, long a3, long a4 );
long syscall4( long n, long a0, long a1, long a2, long a3 );
long syscall3( long n, long a0, long a1, long a2 );
long syscall2( long n, long a0, long a1 );
long syscall1( long n, long a0 );
long syscall0( long n );
#endif
#endif
syscall.c
/* Copyright (c) 2015, Louis P. Santillan
* All rights reserved.
* See LICENSE for licensing details.
*/
#include
#ifdef __LP64__
#include
#else
#include
#endif
#define __SYSCALL_OUTPUT_REG__ "=a" ( ret )
#define __SYSCALL_CHK_ERROR__() \
ret = ( 0 > ret ? errno = -ret, -1 : ret )
#ifdef __LP64__
#define __SYSCALL_OPCODE__ "syscall"
#define __SYSCALL_PREAMBLE__() \
register long r10 __asm__( "r10" ) = a3, \
r08 __asm__( "r8" ) = a4, \
r09 __asm__( "r9" ) = a5
#define __SYSCALL_INPUT_REGS__ \
"a" ( n ), "D" ( a0 ), "S" ( a1 ), "d" ( a2 ), \
"r" ( r08 ), "r" ( r09 ), "r" ( r10 )
#define __SYSCALL_CLOBBERS__ "rcx", "r11", "memory"
#else
#define __SYSCALL_OPCODE__ "int $0x80"
#define __SYSCALL_PREAMBLE__() \
register long ebp __asm__( "ebp" ) = a5
#define __SYSCALL_INPUT_REGS__ \
"a" ( n ), "b" ( a0 ), "c" ( a1 ), "d" ( a2 ), \
"S" ( a3 ), "D" ( a4 ), "r" ( ebp )
#define __SYSCALL_CLOBBERS__ "memory"
#endif
long syscall6( long n, long a0, long a1, long a2, long a3, long a4, long a5 )
{
long ret;
__SYSCALL_PREAMBLE__();
__asm__ volatile( __SYSCALL_OPCODE__
: __SYSCALL_OUTPUT_REG__
: __SYSCALL_INPUT_REGS__
: __SYSCALL_CLOBBERS__ );
__SYSCALL_CHK_ERROR__();
return( ret );
}
#ifdef __RT0_WITH_FASTER_SYSCALL__
#ifdef __LP64__
#define __SYSCALL_PREAMBLE5__() \
register long r10 __asm__( "r10" ) = a3, \
r08 __asm__( "r8" ) = a4
#define __SYSCALL_PREAMBLE4__() \
register long r10 __asm__( "r10" ) = a3
#define __SYSCALL_PREAMBLE3__()
#define __SYSCALL_PREAMBLE2__()
#define __SYSCALL_PREAMBLE1__()
#define __SYSCALL_PREAMBLE0__()
#define __SYSCALL_INPUT_REGS5__ \
"a" ( n ), "D" ( a0 ), "S" ( a1 ), "d" ( a2 ), \
"r" ( r08 ), "r" ( r10 )
#define __SYSCALL_INPUT_REGS4__ \
"a" ( n ), "D" ( a0 ), "S" ( a1 ), "d" ( a2 ), \
"r" ( r10 )
#define __SYSCALL_INPUT_REGS3__ \
"a" ( n ), "D" ( a0 ), "S" ( a1 ), "d" ( a2 )
#define __SYSCALL_INPUT_REGS2__ \
"a" ( n ), "D" ( a0 ), "S" ( a1 )
#define __SYSCALL_INPUT_REGS1__ \
"a" ( n ), "D" ( a0 )
#define __SYSCALL_INPUT_REGS0__ \
"a" ( n )
#else
#define __SYSCALL_PREAMBLE5__()
#define __SYSCALL_PREAMBLE4__()
#define __SYSCALL_PREAMBLE3__()
#define __SYSCALL_PREAMBLE2__()
#define __SYSCALL_PREAMBLE1__()
#define __SYSCALL_PREAMBLE0__()
#define __SYSCALL_INPUT_REGS5__ \
"a" ( n ), "b" ( a0 ), "c" ( a1 ), "d" ( a2 ), \
"S" ( a3 ), "D" ( a4 )
#define __SYSCALL_INPUT_REGS4__ \
"a" ( n ), "b" ( a0 ), "c" ( a1 ), "d" ( a2 ), \
"S" ( a3 )
#define __SYSCALL_INPUT_REGS3__ \
"a" ( n ), "b" ( a0 ), "c" ( a1 ), "d" ( a2 )
#define __SYSCALL_INPUT_REGS2__ \
"a" ( n ), "b" ( a0 ), "c" ( a1 )
#define __SYSCALL_INPUT_REGS1__ \
"a" ( n ), "b" ( a0 )
#define __SYSCALL_INPUT_REGS0__ \
"a" ( n )
#endif
long syscall5( long n, long a0, long a1, long a2, long a3, long a4 )
{
long ret;
__SYSCALL_PREAMBLE5__();
__asm__ volatile( __SYSCALL_OPCODE__
: __SYSCALL_OUTPUT_REG__
: __SYSCALL_INPUT_REGS5__
: __SYSCALL_CLOBBERS__ );
__SYSCALL_CHK_ERROR__();
return( ret );
}
long syscall4( long n, long a0, long a1, long a2, long a3 )
{
long ret;
__SYSCALL_PREAMBLE4__();
__asm__ volatile( __SYSCALL_OPCODE__
: __SYSCALL_OUTPUT_REG__
: __SYSCALL_INPUT_REGS4__
: __SYSCALL_CLOBBERS__ );
__SYSCALL_CHK_ERROR__();
return( ret );
}
long syscall3( long n, long a0, long a1, long a2 )
{
long ret;
__SYSCALL_PREAMBLE3__();
__asm__ volatile( __SYSCALL_OPCODE__
: __SYSCALL_OUTPUT_REG__
: __SYSCALL_INPUT_REGS3__
: __SYSCALL_CLOBBERS__ );
__SYSCALL_CHK_ERROR__();
return( ret );
}
long syscall2( long n, long a0, long a1 )
{
long ret;
__SYSCALL_PREAMBLE2__();
__asm__ volatile( __SYSCALL_OPCODE__
: __SYSCALL_OUTPUT_REG__
: __SYSCALL_INPUT_REGS2__
: __SYSCALL_CLOBBERS__ );
__SYSCALL_CHK_ERROR__();
return( ret );
}
long syscall1( long n, long a0 )
{
long ret;
__SYSCALL_PREAMBLE1__();
__asm__ volatile( __SYSCALL_OPCODE__
: __SYSCALL_OUTPUT_REG__
: __SYSCALL_INPUT_REGS1__
: __SYSCALL_CLOBBERS__ );
__SYSCALL_CHK_ERROR__();
return( ret );
}
long syscall0( long n )
{
long ret;
__SYSCALL_PREAMBLE0__();
__asm__ volatile( __SYSCALL_OPCODE__
: __SYSCALL_OUTPUT_REG__
: __SYSCALL_INPUT_REGS0__
: __SYSCALL_CLOBBERS__ );
__SYSCALL_CHK_ERROR__();
return( ret );
}
#endif
c语言运行时start函数入口。
/* Copyright (c) 2015, Louis P. Santillan
* All rights reserved.
* See LICENSE for licensing details.
*/
#include
#ifdef __LP64__
#define __STARTUP_PREAMBLE__() register long rax __asm__( "rax" )
/* Setup the base */
/* argc = RDI = [ RSP ] */
/* argv = RSI = [ RSP+8 ] */
/* envp = RDX = [ argv+8*argc+8 ] */
/* align the stack */
#define __STARTUP_ASM__ \
"pop %rbp\n\t" \
"mov %rsp, %rbp\n\t" \
"mov (0)(%rbp), %rdi\n\t" \
"lea (8)(%rbp), %rsi\n\t" \
"lea (8)(%rsi,%rdi,8), %rdx\n\t" \
"and $-16, %rsp\n\t"
#define __STARTUP_GETRETVAL__ "=a"( rax )
#define __STARTUP_RETVAL__ rax
#else
#define __STARTUP_PREAMBLE__() register long eax __asm__( "eax" )
/* Setup the base */
/* Fix GCC's 'helpful" 16-byte alignment */
/* argc = ECX = [ ESP ] */
/* argv = EDX = [ ESP+8 ] */
/* envp = EAX = [ argv+8*argc+8 ] */
/* align the stack */
/* push args onto re-aligned stack */
#define __STARTUP_ASM__ \
"mov %esp, %ebp\n\t" \
"add $0x1c, %ebp\n\t" \
"mov (0)(%ebp), %ecx\n\t" \
"lea (4)(%ebp), %edx\n\t" \
"lea (4)(%edx,%ecx,4), %eax\n\t" \
"and $-16, %esp\n\t" \
"push %eax\n\t" \
"push %edx\n\t" \
"push %ecx\n\t"
#define __STARTUP_GETRETVAL__ "=a"( eax )
#define __STARTUP_RETVAL__ eax
#endif
/* pointer to array of char* strings that define the current environment variables */
char **__environ;
int errno;
void _start( void ) __attribute__((noreturn));
void _start( void )
{
__STARTUP_PREAMBLE__();
__asm__ volatile( __STARTUP_ASM__
"call main" );
_exit( __STARTUP_RETVAL__ );
for(;;);
}