您的位置:首页 > 运维架构 > Linux

Linux内核0.12——内核编程语言和环境

2012-10-29 09:15 246 查看
/********AT&T 汇编格式********/

1、为了维持与gcc输出汇编程序的兼容性,as汇编器使用AT&T系统V的汇编语法,这里主要说明一下它与intel汇编的语法区别

2、AT&T与intel汇编语法格式的区别

1)寄存器引用:mov %eax,%ebx

2)操作数顺序:mov %eax(源),%ebx(目的)

3)立即数格式:mov $4,%ebx(如果不加$,则认为4是地址);mov value,%ebx(可以直接引用符号常数);mov $value,%ebx(引用了符号常数作为地址)

4)操作数长度:movb %eax,%ebx(movb为mov byte ptr,movw为mov word ptr,movl为mov long ptr)

5)跳转指令:ljmp $section,$offset;lcall $section,$offset;lret $stack_adjust(等同于intel汇编格式的:jmp far section:offset;call far section:offset;ret far stack_adjust)

6)内存引用:section:[base + index*scale + disp](等同于intel汇编:section:disp(base,index,scale))

/*********嵌入汇编********/

1、C程序的产生过程(gcc编译器):.c源文件----(cpp预处理)---->.c纯C----(cc编译器)---->.s汇编程序----(as汇编器)---->.o目标文件----(.a库文件+ld连接器)---->可执行文件

2、嵌入汇编格式:

__asm__("assemble language"
:output register
:input register
:to be changed register);
说明:1、为了让gcc编译产生的汇编程序中寄存器前面有一个%,在嵌入汇编语句中寄存器名称前需加两个%;2、输出寄存器格式为"=a"(__res),这是指将eax的值输出到__res变量中去,具体的Google。。。3、在前几个寄存器中已经包括了要被改变的寄存器的时候,就不要在要被改变的寄存器一项添加了

简单的strcpy函数代码:

char * strcpy(char * dest,const char * src)
{
__asm__("cld\n"
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
::"S"(src),"D"(dest));
return dest;
}
3、C函数调用机制:“设置”,初始化栈帧结构;“主体”,执行函数的实际计算操作;“结束”,恢复栈状态并从函数中返回

4、C和汇编的互相调用:

在汇编中调用C:比较自由,只要是在栈中适当位置的内容就都可以作为参数供C函数使用;我们可以不用CALL指令而采用JMP指令来达到调用函数的目的

在C中调用汇编:方法和前者一样,重点仍然是对函数参数在栈中位置的确定上

/******目标文件格式及其链接*******/

1、目标文件组成(具体参见include/a.out.h文件):

依次序总的为:a.out文件头、代码部分、数据部分、代码重定位信息、数据重定位信息、符号表和字符串表

执行头部分:1)魔数字段值:0x107魔数OMAGIC指明文件是目标文件或者是不纯的可执行文件;0x10b魔数ZMAGIC指明文件为需求分页处理的可执行文件;2)a_text、a_data和a_bss分别指明后面只读的代码段、可读写的数据段和数据段后面未初始化数据区域的长度;3)a_entry指明了程序代码开始执行的地址;4)a_syms、a_trsize和a_drsize分别指明了数据段后面符号表、代码和数据段重定位信息的大小。

重定位信息部分:重定位信息为struct relocation_info{..}结构体;在代码段被重定位到不同的基地址处时,重定位项指出需要修改的地方;在模块文件中存在对未定义符号引用时,当此未定义符号最终被定义时连接程序就可以使用相应重定位项对符号值进行修改。

符号表和字符串部分:这是目标文件的最后部分;符号表记录项需要记录该符号的符号名、符号名字符串在字符串表中的偏移位置、符号的类型、是否为全局的、符号的值

2、查看目标文件中的具体值:

objdump -h hello.o
查看可执行文件的具体值:

objdump -h hello
3、链接程序的任务

1)给执行文件进行存储空间分配操作。一旦存储位置确定,链接程序就可以继续执行符号绑定操作和代码修正操作

2)把所有模块中相同类型的段组合连接在一起,在输出文件中为指定段类型形成单一一个段

4、内核加载可执行文件

1)首先,内核根据文件头部结构中的信息首先判断文件是不是一个合适的可执行文件

2)然后系统在用户态堆栈顶部为程序设置环境参数和命令行上输入的参数信息块并为其构建一个任务数据结构

3)接着在设置了一些相关寄存器值后利用堆栈返回技术去执行程序。执行程序映像文件的代码和数据将会在实际执行到或用到时利用需求加载技术动态加载到内存中

/*****makefile*****/

参见:/article/8410339.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: