gcc编译过程

命令模式下,
:%!xxd 是文本文件的16进制形式,返回文本则是后面多一个-r;二进制则是后面多一个-b;
文本形式都是asc码对应的,二进制也是,只是地址都是虚拟地址,是一个进程里面的,所以有可能从零开始;

编译总结:
一般gcc默认就是编译成可执行文件,并且是a.out;如果后面加参数-o则是指定可执行文件名称的;
一般系统不是根据后缀名判定的,是根据文件形式或者内容;
然后吧如果是加-E则只是预编译而已,而且就是把宏或者头文件替换进来而已,后缀是i;然后加-S则是将程序编译成汇编代码,后缀是s;然后就是加-c(小写的)则是将汇编编译成可重定向的目标文件,此时还不是可执行文件,里面的内存地址还没有跟具体的物理内存地址联系起来;-o则只是指定目标名称,gcc会自动分析应该生成什么养的程序;最后-l则是进行链接,将各个用到的库(静态的需要的整个代码都弄进来,动态的则是登记或者记录相关信息,函数地址或者入口地址之类的吧);还有一些线程库或者函数库之类的;默认动态的,或者共享的;其他的显示标记;

编译过程:

预编译确实是会把好多库函数导入进来,汇编也是;然后可重定向的文件也是2进制的;只是不可执行而已;所有的都是吧;
编译时则是-I是在特定范围内寻找头文件;-L则是链接特定的库文件;-wall则是指打印所有的警告信息,就是一些warnning吧;-WL传递给链接器什么呢?好还有-O或者-O2则是优化等级;一般编译程序时要加-g吧,就是调试信息;
否则无法运用gdb;
会显示没有符号表被读取;

交叉编译跟本地编译差别不打,只是为了能够在pc上linux编译的能在arm上用而已;可能就编译器参数有点不同吧;而且arm—linux-argro-gcc大概就是这个意思吧;

link:

首先链接库分为两种,静态库和动态库;但并不是以后缀名为区分的;也就是lib与lib*a不一定是静态库也可能是生成特殊动态库导出的符号表之类的;所谓动态链接与静态链接更多的是为了区分执行时间吧,前者是链接时复制粘贴进去;后者则是是链接时只复制粘贴函数声明或者其他的地址信息,加载器运行时才复制粘贴,而且好像是复制到堆栈之间;然后文件大小之类的,应该很容易理解吧;首先静态库:感觉就是将目标文件包装了一下;ar -cr hello1.o hello2.o -o libhello.a 啊;甚至nm一下,里面也直接是目标文件,可能就多了一下文件数据吧,查找之类的;然后链接时,因为动态链接有节省内存,易于升级,并且对性能影响不太大等因素,所以默认先动态链接吧;只要不加-static;总是先优先找lib*.so;但是如果没有的话,估计也要静态链接了吧;编译 可执行文件时:gcc -o main main.c ./libsm.a 或者gcc -o main main.c -lsm -L. 前面是利用的-l命令,所以要指定目录范围,否则就要先当前然后环境变量然后默认目录了;(-L跟路径或者搜索范围,-l则是库文件名,-I也是头文件的范围,-i一般不用吧,用的话也就是绝对路径了);链接时加上-static则就是强制静态链接了,也就是要找静态库了;还有就是静态库好像是整体代码,都写进去;但那个静态库里面就包含了所有的代码么?还是链接时也是临时加载的呢?
动态库:生成的话,加一个 gcc -o libhello.so -shared hello.c(或者hello.o);生成动态库时有可能附带产生lib*.a;然后编译可执行文件时,gcc -o main ./libhello.so main.c或者gcc -o main -L. -lhello main.c ;然后就是执行时还是找不到共享库,因为执行时加载器无视当前目录,只会去找环境变量或者配置文件或者默认路径,所以要修改(临时变量永久文件)或者复制默认路径;毕竟c库就是动态,也在那里;修改环境变量就是export LD_LIBRARY_PATH = .:$LD_LIBRARY_PATH  ;可执行文件是动态链接还是静态链接,可以用 ldd main 来查看;
编译器找库就两种方式,要么直接给出库文件,要么就用两个(-L-l)命令定位;
现在就是不知道静态库与动态库,静态链接与动态链接有什么区别?
静态库可以认为是把若干个目标文件包装一下,如果用到其中的代码,那就是全部都给你了;可以确定的是静态链接无法链接动态库;而动态链接可以链接静态库;只是链接静态库要大一点;很有可能是也是讲所有的代码拷过来了,只是那些动态库才在运行时加载;也就是说,静态库无论给谁都是所有的代码;只是静态链接吧所有的都弄过来了;包括标准库之类的;也就是可以完全独立的运行了;而动态库只是给了相应的函数头或者函数表而已;在运行时加载;这下算是清楚了;静态链接最大,动态链接静态库次之;动态链接动态库最小;但是共享库本身要大好多;可能是本身更复杂,要记录的信息更多,不仅是函数已经实现还有就是要记录段的信息,然后寄存器之类的;不像静态库只是目标代码而已;

默认是链动态库的,静态库是要-static的,链接顺序是命令行,环境变量,然后默认/lib,/usr/lib,/usr/loacal/lib;动态库就是命令行,环境变量后者配置文件,然后也是默认路径,应该有一个专门的目录文件吧;

include<sys/time.h>和include<time.h>的区别:
前者是linux下的,一般会引入后者,前者有gettimeofday()函数;后者则是c99标准头文件,里面有好多求时间的函数;其中clock()函数;最小粒度是毫秒;一般gcc编译时是知道默认路径usr/include的下的路径的;那是系统头文件;安装时就自带的;然后就是有时会安装在子目录里面,比如:i386_ubuntu之类的;
vim里面换行只是识别\n估计;
双核四线程是两个物理核心,然后都超线程了;可以同时运行四个线程,所谓多线程并不是指硬件的而是指进程里分的,只是单核单线程也能运行好多进程里的线程吧,只是切换而已;
还有就是x86比arm功能强好多,架构,指令集,然后还有指令发射速度,分支预测啊,流水线啊之类的;还有三级缓存,L1就是静态ram了,二级则是高速动态,三级不太清楚了,不过也是差不多吧;

file filename 查看文件类型

lld filename 查看可执行程序的依赖共享库
nm filename 查看二进制文件里面的函数信息,是否定义之类的

strings 查看二进制的文件内容


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值