链接学习笔记(1)–重定位解释

  • A+
所属分类:操作系统

前言:
最近发现了一个好玩的东西:链接
在我们平常写的多文件项目中,经过编译汇编链接等生成.o文件,我们称之为目标文件
正文:在最近看《深入理解计算机系统》过程中,有两段代码不是很理解,特此分享
a1.c
链接学习笔记(1)--重定位解释
b1.c
链接学习笔记(1)--重定位解释
由于我编写a1.c的时候x没有排在y的前面,所以与书有些出入,原书中的大致含义是在经过链接之后,x的值会把y的值覆盖掉。其意思就是在调用f函数的时候会把x看成double类型的东西执行。但是书中还说,如果出现一个强符号,一个弱符号的话,应该以强符号为准。本例中强符号应该是int类型的,弱符号是double类型的,难道b1里面不应该也是int类型的嘛?
对于初学者来说,这应该是比较沙雕的错误了,但是我的确想了一天才整明白嘿嘿。原因就是以上所说的是重定位的事情。重定位是啥?就是对于没有交代清楚的符号(声明未定义)进行重新定位。比如说,在a1.o中重定位表里面应该包含f,b1.o中应该包含x,这是没有错误的,那重定位做了啥?说白了就是在编译的时候,编译器不知道声明未定义的符号有没有可能在其他文件中定义,不敢报错,所以先随便生成一个假地址,然后在生成一个重定位表,等到链接的时候,根据这个重定位表把那个假地址给改对了,如果存在改不过来的假地址,就会有undefined reference的报错。
好了,为了验证上面的想法,展示一下a1.o和b1.o的重定位表
链接学习笔记(1)--重定位解释
链接学习笔记(1)--重定位解释
可见,强符号,弱符号只是重定位用的,实际将高级语言转换成汇编的时候,只能看到本文件中定义的数据类型,最后用重定位表给你改个地址,就完了。
所以在b1.o里面只能看见double类型数据,所以他是双字节的东西。然后重定位到int类型的地址,将x,y都给覆盖掉。
链接学习笔记(1)--重定位解释
链接学习笔记(1)--重定位解释
可以看见,两段代码不同的地方就是改了个地址。
这里面有个小插曲,就是我之前f函数写的是给x赋值成-0.0,就会发现他总是从40200地址读什么东西,然后送给%xmm0(这是一个双字寄存器,用来给双字类型数据赋值,并结合movsd使用),之后把%xmm0的东西送给重定位之后的x(int),我不理解的是,40200是啥,后来发现,-0.0被放在rodata也就是只读数据段。。比如printf里面的参数都往这里放。后来我把-0.0改成了0,就用了pxor指令,这个就是给xmm0清零然后送进去。
后记:以上仅为个人想法/猜测,如有不当欢迎指正!

w3cjava