一 实验准备
下载实验代码源文件
$ git clone
https://os.inf.tu-dresden.de/repo/git/mkc.git
$ make后产生如下源文件
二 实验分析
打开user/src/start.S
汇编源码文件内容如下:
.text //编译器关键词 指定后续编译出来内容放在代码段(可执行)
.global __start //编译器关键词 告诉编译器后续跟的为全局变量名
__start: //编译链接后的程序起始地址
mov $stack_top, %esp
call main_func //1. 将函数返回地址入桟 2. 让指针%eip指向函数开始处
ud2 // 让CPU产生invaild opcode exception的软件指令,内核一旦发现该指令,立即停止运行
打开user/src/user.cc
C++源码文件:
#define NORETURN __attribute__((noreturn)) //表示此函数无返回值
#define EXTERN_C extern "C" //限定extern类型, 修饰的变量或函数按C语言方式编译与链接EXTERN_C NORETURN
void main_func ()
{
while (1) ;
}
打开user/src/linker.ld
链接(C程序与汇编)脚本文件: 描述输入文件中的节如何被映射到输出文件中,并控制输出文件的内存分布
OUTPUT_FORMAT("elf32-i386") //输出目标文件格式
OUTPUT_ARCH("i386") //运行平台
ENTRY(__start) //设置程序入口点
PHDRS //此命令仅在生成elf文件时有效,elf目标格式用program headers 程序头来描述如何被载入内存
{
data PT_LOAD FLAGS(6);//PT_LOAD为属性,表示程序运行时应被加载入内存
text PT_LOAD FLAGS(5); //描述定义了两个段
}
SECTIONS // 描述输出文件的内存布局,告诉ld如何把输入文件的sections映射到输出文件的sections
{. = 0x1000 + SIZEOF_HEADERS; //定义当前地址
.data :
{
BYTE(42); // 分配一个字节,存放值42
. = ALIGN(0x1000); //以一页4KB为单位对齐桟指针
stack_top = .;
*(.data);
*(.bss); //将输入文件中的所有.data.bss section都链接到输出文件的.data section 部分
} : data //将输出文件的.data section分配到PHDRS命令定义的data的section中
.text : &nb