参见《程序员的自我修养》中的MiniCRT
下面给出源代码
void mini_crt_entry(void)
{
int ret = 0;
int argc;
char **argv;
char *ebp_reg = 0;
//将寄存器EBP的值存入ebp_reg中
asm("movl %%ebp, %0 \n":"=r"(ebp_reg));
argc = *(int *)(ebp_reg + 4);
argv = (char **)(ebp_reg + 8);
//堆栈初始化
if (!mini_crt_heap_init())
crt_fatal_error("heap initialize failed");
//io初始化
if (!mini_crt_io_init())
crt_fatal_error("io initialize failed");
ret = main(argc, argv);
exit(ret);
}
哈哈,这就是程序的入口
mini_crt_heap_init()初始化堆栈
mini_crt_io_init()初始化I/O
void exit(int exitCode)
{
asm("movl %0, %%ebx \n\t"
"movl $1, %%eax \n\t"
"int $0x80 \n\t"
"hlt \n\t"::"m"(exitCode));
}
原来exit()的函数是系统调用进入内核态
好了,看看怎么编译运行
gcc -c -ggdb -fno-builtin -nostdlib -fno-stack-protector test.c
-fno-builtin
不接受不是两个下划线开头的内建函数(built-in function).目的就是为了关闭GCC内置函数功能
-nostdlib
不使用任何来自Glibc,GCC的库文件和启动文件
-fno-stack-protector:
禁用堆栈保护,最近版本的GCC会在vfprintf这样的变长参数函数中插入堆栈保护函数,如果不关闭,会在使用MiniCRT时发生"__stack_chk_fail"函数未定义错误
ld -static -e mini_crt_entry entry.o test.o minicrt.a -o test-e mini_crt_entry 指定函数入口
源代码:http://yunpan.cn/Q7G9T6rN9RUnf 提取码 c642
编写了makefile文件,编译直接make命令,运行使用make run命令
test.c是测试程序,发现bug请及时联系