运行阶段:函数调用的背后---代码重定位

讨论问题:

1.函数调用的背后
2. 什么是重定位。

3.1 重定位

程序是按顺序,从起始地址依次往下运行。当需要破坏这种顺序执行跳转到某一具体目标执行时,需要告知CPU这个目标(符号)所在的具体地址。而这个地址需要通过计算目标符号位于程序中的位置来获得。计算目标地址的过程称为重定位。重定位有静态重定位和动态重定位,在这主要分析的是静态重定位。

3.2 函数调用的背后–代码重定位

创建一个main.c文件,编写main函数,创建test.c文件,编写函数名为hello、world两个空函数,并在main函数中先后调用hello、world函数。

/* C语言程序:test.c */
void hello (void)
 {
 	printf("hello func...\n");
 }
void world (void) 
{
	printf("world func...\n");
}

/* C语言程序:main.c */
int main (void)
{
        hello();
        world();
        return 0;
}

当调用函数hello时,根据hello的地址,CPU通过执行相关的指令后(可能是跳转指令,也可能是通过修改PC寄存器中的值为hello地址的指令,还可能是其他类型的指令,后续讨论),开始执行hello函数。因此,确定hello/world函数在程序中的地址就是关键所在。

如果你之前看过u-boot重定位相关的资料,会不会产生这样的疑问
不是说重定位代码是位置相关代码?而且重定位后还需要确保运行地址与链接地址一致,不然就会找不到目标符号,导致程序运行出错。而你这实现hello、world两个函数的调用明明是位置无关代码,怎么能算是重定位呢。如果你没有这个疑问,请忽略它,不要被它所影响。

将这两个文件编译但不链接,来分析是否需要进行重定位:

编译但不链接命令:arm-none-linux-gnueabi-gcc -c main.c test.c

编译后的main.o二进制文件反汇编得到的汇编程序:

/* 反汇编程序: arm-none-linux-gnueabi-objdump -d main.o*/
00000000 :
   0:   e92d4800        push    {fp, lr}
   4:   e28db004        add     fp, sp, #4
   8:   ebfffffe        bl      0 
   c:   ebfffffe        bl      0 
  10:   e3a03000        mov     r3, #0
  14:   e1a00003        mov     r0, r3
  18:   e8bd8800        pop     {fp, pc}

并查看该二进制文件的重定位表,来判断是否需要重定位:

/* 重定位表: arm-none-linux-gnueabi-objdump -r main.o */
RELOCATION RECORDS FOR [.text]:
OFFSET        TYPE            	VALUE 
00000008      R_ARM_CALL        hello
0000000c      R_ARM_CALL        world

根据重定位表的信息可知man.o是需要进行重定位,并且有两个重定位入口地址分别是0x00000008、0x0000000c。
根据main.c的反汇编程序,在0x00000008和0x0000000c地址处的指令是bl 跳转指令,只是此时跳转的目标地址未知,默认配置为0

那么此处bl跳转指令的目标地址是在什么时候确定的,换句话说,静态重定位发生在什么时候,答案是静态链接阶段。

(如你喜欢,更多知识,快人一步)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值