[音乐] 上一段视频呢我们介绍了data节当中的重定位过程。
下面呢我们介绍text节当中的重定位过程,也都是采用绝对地址的定位方式。
这个swap.c当中有这样4个附值语句,4个附值语句当中
有很多地方都应用了相应的定义符号,比如说这个附值语句当中
引用了2个符号,左边右边各引用了1个。
这个附值语句当中右边是一个引用的符号,第三个附值语句当中,左边右边都是引用的符号。
第4个附值语句呢,左边是引用的符号,这里面的这个temp,因为它是一个局部变量。
所以它不需要引用,因此我们可以看到,它最后生成的text节当中
对应于第一条附值语句的是这样的一条指令。
这条指令当中有两个地方需要引用。
第8的这个位置,这是第6的位置,这是0123456,这第6。
这第8的这个位置开始需要引用。
然后第c这个位置开始也需要引用,引用的重定位条目,通过 obj
dump以后呢,显示出来是这样子的,这是第一条附值语句
对应的mov指令当中,它的原操作
数和目操作数,都需要进行重定位。
都是一种引用,它的原是一个地址值。
目呢是送到某一个变量,也就是bufp1那个
变量所在的空间里面,而这个地址值是应用了buf这个定义,这个呢应用了bufp1。
第2个附值语句当中,有1个地方需要 进行重定位,就是在位移量为11的这个地方。
这是10,这是11,位移量为11的这个地方需要进行引用。
那么引用的是bufp0,引用的是bufp0。
都是绝对地址方式,这也是绝对地址方式。
第3条附值语句,左边右边都需要引用,左边是bufp0
所指的那个内容,bufp0那个地方的内容被附的值呢是bufp1所指的那个单元的内容。
所以这个里面用到了1234,4条
mov指令,这个我们也可以猜到,因为这个地方有2个星号,所以是要间接群指的。
第一个需要重定位的地方,是在1b这个 地方,这个地方应用的是bufp0。
应用的是bufp0,是在左边这个地方。
然后呢,第2个需要应用的地方,是在
以21这个地方,这是1f,这是20,这是21开始的地方。
就是off set是21开始的地方,然后也是绝对地址方式。
应用的是bss节里面的起始位子。
因为这个bufp1 是没有初始值的,没有给它进行初始化,所以
呢它是在bss节里面,就是bufp1
是定义在bss这个节里面的,因为它是
静态的全局变量,但是它没有付出值,所以这个地方
我们可以看出应用的是bss节的起始位子。
就是bufp1,然后最后一条附值语句 左边有1个应用处,也是应用的bufp1,所以我们可以
看到,在这个位置开始,需要进行重定位。
也就是2a这个位置,这是29,这是2a,这个开始需要进行
重定位,重定位应用符号也是bss,因为它是busp1。
所以我们可以看到,在这个text 节当中,有6个地方需要进行重定位,就是
在第8,第c,第11
第1b,第21,第2a,这些位置。
这是我们刚才给出来的6个重定位的地方。
那么我们来看一下怎么进行重定位,我们已经知道buf的 地址是8049620。
然后bufp0紧接在buf后面。
它是8049628,这2个地址已经知道了,下面我们来看一下第一条。
mov指令当中的2个需要重定位的地方是如何进行的。
首先我们看,这个位置,就是c这个位置,它的重定位。
这个重定位所应用的符号是buf,也就是说我们要在这个地方
给它进行重定位,也就是这个附值语句右边。
这个右边实际上是buf1,下标为1的那个数组元素
的地址,下标为1的那个数组元素的地址,我们可以猜到应该是buf的首地址。
加4,为什么呢,因为buf当中每一个数组元素都是4个字节。
所以第1个数组元素的地址应该是它的起始地址加4。
也就是在c这个地方的这个重定位值,
就是这一个它的值,这个值应该是把buf的首地址加4。
这个4因为它的初始值已经是4了,就是说,它在进行编译的时候,
根据这边的下标是1,已经在汇编指令
当中设定了一个初始值4,因为这个下标是1。
所以相当于起始地址当对于buf的首地址是4个字节的地方,所以它的这个初始值是4。
因此,汇编器,就是汇编程序把汇编指令翻译成机器代码的时候
这个地方就是4,就是00000004,对应
的这边,汇编指令当中的这个4,这个4实际上就是 在绝对地址的重定位方式当中,把应用
的这个符号,加上原来的初始值4 得到的这个地址,就是重定位以后的值,重定位
以后的值,就是把buf首地址加4以后得到的这个值。
就会填到这来,然后我们再来看8这个位置。
8这个位置,实际上它应用的是
bss节,因为这个附值语句左边是bufp1。
而bufp1的地址,实际上就是bss节 的首地址,这个首地址我们假定,合并以后
它就是等于它,因此绝对地址的重定位方式,只要把这个地址直接
填到这个位置当中去就可以了。
8这个位置,从这个位置开始,存放的就是 这个应用的目标出的地址,直接填进去。
同样的,对于这个8和c,我们已经讲完了。
8这个位置就是这个地址,8049700。
所以按小端方式的话就是倒过来写,然后c这个位置呢,就是8049624
小端方式就是倒过来,同样的原理,我们在这个11这个地方。
把bufp0的值填到这来,就可以了,而bufp0我们在
前面已经算出来它是8049628,所以小端方式倒过来就可以了。
1b这个位置,应用的是bufp0,因此这个地方也是
8049628,然后21这个位置
应用的是bss的首地址,就是bufp1的 值,就是8049700,8049700。
2a这个位置,同样的是bss,也是
8049700,这样的话6个位置的重定位值就都有了。
重定位以后,就把相应的这些值替代原来的这些值,就会 得到新的一条指令,就是重定位以后的
text节当中的这个信息,这样的话我们就把这个例子
当中所有重定位的地方都已经完成,所有重定位的操作都完成了。
在前面我们讲过,在main.o里面进行重定位的时候,call指令
call这个swap函数的起始地址的时候,我们知道重定位值
是09,所有我们在这呢,这个call指令就变成了这样的一个指令。
然后,这个main函数,它是从8048380开始的。
一共占了18个字节,因为每一个函数都要按照4字节边界对齐。
所以呢,swap函数开始的这个地址,就 不能够用8948392开始。
应该是从8048394开始,它是4的倍数。
因此,在填了2个空指令,空操作指令。
再来2个字节,所以swap函数就从8048394开始。
8048394和当前的pc,就是call指令下一条指令的地址,8048
38b之间,差9个字节,所以这个地方填的是偏移量。
从刚才我们讲的那个例子当中我们知道,在这个地方进行了重定位,这个重定位的这个值
实际上是buf1,下标为1的
buf数组元素的首地址,就是它,把它附给 bufp0那个地方,然后得到这条指令的
这个机器指令的01序列,然后同样呢,后面,这个我们刚才才讲
过的,这些都把它重定位好了,所以这样的话重定位以后我们就得到
合并以后的可执行文件当中的每一条指令的代码,这些指令的代码
就可以直接执行,这个main是从这个地方开始,swap紧接在main后面,从这个地- 方开始。
它们共同构成了一个.text节,在这个里面
call指令,就是操作数为e8的这条call指令,它的功能
就是先入暂,把call指令下一条指令的地址,也就是这个地址
pc,当前pc的内容,执行call指令的时候 pc里面的内容应该下一条指令的地址,就是这个值。
啊这个值,先压暂,先找一个暂,长4个字节出来,然后压暂。
然后呢,再把这个目标,也就是8048 394,就是当前这个pc加9这个偏移量
是9,加出来的就是转移到的这个目标地址,swap的首地址。
放到pc里面,就是eip计算机里面,执行call指令,完了以后下条
指令就执行这个地方的这条指令,就转到了swap执行。
这是重定位以后的这个代码段的指令。
[音乐] [音乐]