C与汇编混合编程&&ELF文件格式解析

准备工作:C与汇编的混合编程ELF文件格式解析,这是《自己动手写操作系统》第五章的准备工作,主要讲解C与汇编混合编程的一些知识,并讲解ELF文件的相关知识,为有C语言写操作系统做准备。

1.关于系统调用sys_write

Linux的系统调用通过int 80h实现,用系统调用号来区分入口函数,它的作用类似与dos的中断。

      
        mov edx, len     ; 参数三:字符串长度
        mov ecx, msg     ; 参数二:要显示的字符串
        mov ebx, 1       ; 参数一:文件描述符(stdout) 
        mov eax, 4       ; 系统调用号(sys_write) 
        int 0x80         ; 调用内核功能

2.C与汇编混合编程


2.1 64位机器上目标文件不兼容问题: “could not read symbols"

    如果我们按照书上的命令:

nasm -f -o foo.o foo.asm
gcc -c o bar.o bar.c
ld -s -o foobar foo.o bar.o
    假如你是在64b的机器上,就会收到出错信息:
 “could not read symbols"
    这是因为,你的foo.o &&bar.o 分别是32b的目标文件和64位的目标文件,所以没法使用链接器进行链接。
解决方法:统一使用32b的elf文件,命令如下
gcc -m32 -c -o bar.o bar.c
ld -m elf_i386 -s -o foobar foo.o bar.o

2.2参数传递问题

    如果一个汇编中定义的函数想要被外部程序引用,需要用关键字导出——global; 如果汇编中用到其他文件定义的函数,需要对函数进行声明,导入——extern;参数入栈顺序——后面的参数先入栈

3.ELF文件格式解析


3.1.为什么需要了解ELF文件格式

    因为linux可执行内核是采用ELF文件格式的,将ELF格式的内核加载到内存之后,如何将控制权转移到内核——我们如何知道程序开始执行的起始地点相对ELF头的位置?加载内核到内存之后,程序应该如何执行?程序执行的时候使用的都是虚拟地址——在ELF文件格式中提供的都是虚拟地址。那么如何将程序加载到对应的虚拟地址?ELF文件格式中存储了很多冗余信息,程序也包含很多个不同的段,那么如何将这些段分别加载到不同的位置?program header一共有多少个,其中分别在文件中的偏移、长度和加载到虚拟地址的位置信息?

    等等这些信息都需要我们了解ELF文件的格式。


3.2ELF文件格式概览


1)想要了解ELF文件的格式,我们需要熟悉一个命令,xxd,这是一个查看二进制文件的常用指令:
    它的常用参数意义如下:
-u:使用大写字母显示内容;
-a:autoskip自动跳过空数据;
-g num:groupby分组大小 1表示1字节
-c cols:每行显示的列数
-l num:一共显示多少单元
-s +/-num:seek,起始单元多远的地方开始显示

2)elf文件格式与后续的相关部分
    想要了解elf文件的具体信息,可以参考这里:elf文件格式完全解析
与后续内容相关的信息如下:

A、在ELF文件头中,包含程序的入口的虚拟地址;

B、每个段在ELF文件中的位置和大小信息,被加载到虚拟内存的位置和大小信息


4.调用原理

首先,我们知道,汇编调用C语言函数实际上是通过call指令来实现的。而call的对象是符号表中的一个符号,实际上,这个符号对应的是一个虚拟地址,也就是说符号表中的符号,是一个虚拟地址。那么call与jmp有什么区别呢

 对于jmp的区别就是:一个是段内调用,一个是段间调用

 对于call则有很大的不同,因为call的调用会对栈产生影响:
   (1)call的近调用不会改变使用的栈,但是栈的内容发生了变化:下一条指令被压入栈;如果有参数,参数被压入栈
   (2)call的远调用会改变使用的栈,由于使用的栈发生变化,因此对于参数有一个拷贝的过程。
      保存当前的ss和esp到被调用过程的栈中
      拷贝参数
      保存当前的cs和eip到被调用过程的栈中

总结:call与jmp的主要区别在于对待返回地址的不同;call远和近调用区别在于对于堆栈ss和sp的信息保存。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值