1 关于符号解析和重定位的思考:
编译生成的.o属于可重定位文件,每个可重定位文件都有自己的符号表。假设当前cpp1.o文件里引用了另一个.o文件中定义的全局变量或者子函数,再最终链接成可执行文件时,linker会从所有.o的符号表统一成一个符号表,然后匹配cpp1.o引用的变量或者子函数是否有定义,从而建立起.o之间的联系。另外,由于单个.o文件符号地址在链接运行前,无法确定变量或者函数的真正地址,我想具体的内存运行地址应该是在最终生成可执行程序时得出。程序运行地址应该是可以通过设置_entry指定的。若未指定,默认linux的应用程序运行地址应该是0x80004000。
2 关于Big Endian 和 Little Endian的思考:
先熟悉这两个概念:
MSB的意思是most significant bit,故名思议,就是重要的比特。假设有值0x12345678,最重要的则是0x12, 因为0x12345678与0x00345678差别非常大;
LSB的意思是little significant bit,故名思议,就是最不重要的比特。假设有值0x12345678,最不重要的则是0x78 因为0x12345678与0x12345600差别不太大;
然后就明白了,Big endian传输/存储,就是说先传最高位,即MSB,即最低地址存储的是0x12,其次才是0x34,0x56 0x78;
Little endian传输/存储,就是说先传最不重要的比特,LSB,即最低地址存储的是0x78,其次才是0x56,0x34,0x12;
3 关于Main 入口的思考:
编写一个应用程序,通常会定义main()函数名,实际上再运行该程序时,再执行到Main函数前已经做了很多事情,在main函数结束后,也要做一些exit对应的事情。
--start-->libc_start_main-->exit()-->_exit();main函数就是在libc_start_main函数中被调用到的。_start参数传递包括argc,argv,以及环境变量env,然后跳转到libc_start_main,最后才跳转到main函数。大致流程如此。具体需要研究linux glibc的/libc/csu源码实现。<<程序员的自我修养>>里面有miniCRT的简单实现,可以用来学习。