01- 复习
tar tvf xxx 查看压缩包内容
区分前后台: 是否能和用户交互
Vmware选桥接模式 会给系统虚拟一个和外部相同网段的ip
02- vim扩展操作
因为不是做嵌入式开发的 所以这些东西不是特别重要
简单过一遍
缩进:
右缩进 两个>>
左缩进 两个<<
4行右缩进 4>>
想把m变量改成n:
15,17s /f/m/g
r替换当前字符
R 替换当前光标后的字符
[d 查看宏:
(这个宏是在上面定义的)
在程序中使用man page:
光标移动到函数身上按K
示例:
这里应该按 3K 查看函数手册页面
在vim里执行shell命令:
!ls(在末行模式下)
:!ls
:!cp
:!man
例如: :!man 2 read
分屏操作:
比如我经常在文档开头和文档结尾处编辑 这个时候可以借助分屏
ctrl+ww
:sp 分屏 (末行模式)
ctrl +w w
:vsp 竖分屏
ctrl +w hjkl 选择性的切换分屏
:wqall 将所有窗口一次性退出
分屏打开另外的文件
:vsp aaa.h
配置文件:
/etc/vim/vimrc
这个配置文件配置的是整个操作系统 对所有用户生效
~/.vimrc 默认是一个隐藏文件
… …(如果想设置 自己百度)
(把vim打造成很强的ide)
03- gcc编译工具和工具链
-I 指定头文件的位置:
hello.c
hello.h
mv hello.h ..
gcc hello.c –I ..
这样就能编译成功了
-c只编译 不进行链接
最耗时的操作是编译
因为编译要一行一行的去检查语法错误
预处理和汇编都不会检查错误
汇编只是简单的翻译
-g 先不讲 后面讲gdb开发再讲
-On 驱动开发才经常会用
翻译成汇编的时候会直接删除这段代码
这段代码指定优化会把中间的没用步骤优化掉
-Wall ( warning all 提示完整的警告信息)
例如:
代码中加了一个不会被使用的变量
然后gcc hello.c –Wall
gcc本来就是一个工具链
GNU编译工具集合器
符号: 全局变量和函数
gcc hello.c
然后可以nm a.out
描述符T(表示在内存TEXT段内部已经实现的)
D 是在data段
U未实现
gcc –c hello.c
得到目标文件 hello.o
nm hello.o
目标文件比可执行文件 符号少很多
也就是说在最后一步链接的时候 会像目标文件里链入很多符号表
printf函数就未实现
printf函数是一个库函数
虽然有include <stdio.h>
但是 printf是在libc库里 libc库是一个动态库
动态库是在程序的运行期间链接
只有 ./a.out的时候 才会把printf跟程序链接到一块
nm 一下之前那个可执行文件 还是U 未实现
这个主要用于反汇编
例如:
objdump –dS hello.o
callq 调用函数
除了可以反汇编a.o
也可以反汇编a.out
ranlib 一般不用 太麻烦了
elf
file hello.o:
LSB 小尾端法存储 低地址存在低字节 高地址存在高字节
可重定位的
所以目标文件也叫 可重定位文件
file a.out:
可执行文件
目标文件和可执行文件都是二进制文件
即使是二进制文件也有属于它的存储格式 即elf格式
readelf命令就是读取这种格式的工具
readelf –a hello.o
大概包括三部分:
elf头 包括节头
重定位节:
符号表:
可执行程序装载到内存的原理
64bit系统内存太大了, 从32bit的示例
0~3G 是用户区
3G~4G 是kernal区
text:代码段 存放代码 int main void 什么的ascii码都翻译成二进制
data: 数据段 常量 字符串
bss: 未初始化的全局变量和未初始化的static变量
栈和堆重合的时候就内存溢出了
ro权限 (read only
rw权限
text段和data段之间有一个rodata
04-静态库
头文件只包含函数声明
真正的函数是在库文件里面
静态库libmytest.a
假如另外的b.out c.out d.out 每个都要添加一份
会复制一份作为程序代码的一部分
如果一个3m的静态库 有100个程序使用 内存中就会多出来300MB
main.c
add.c
mul.c
sub.c
可以制作成静态库函数
gcc main.c –o app –L ./ -l mymath –I ./
-L 指定库位置
-l 指定库的名字
-I 指定头文件位置
04- 动态库
动态链接器
当运行a.out的时候会使用动态连接器加载
运行b.out c.out d.out的时候 都会去加载这个stack和heap之间的动态库
共享代码(不共享数据)的意思是 如果a.out把共享库里一个变量改变了 b.out也会承受这个修改… … 所以一般动态数据库不会共享数据! (了解)
动态链接器 链接器 除了名字像没任何关系
链接器工作在编译阶段
gcc 生成app的时候会用连接器
动态链接器是在程序运行的时候装载
生成可执行文件 然后运行 报错了
问题出在动态链接器不知道在哪找库
指定的方法:
01- 中午复习_动态库
符号: 全局变量 全局函数
函数名 变量名 都是地址值
静态库:编译时
动态库:运行时
Ldd 查看可执行文件执行期间要加载哪些库
这个东西就是动态链接器
动态链接器本质也是一个动态库
.bashrc
类似于vimrc 每次打开终端都会读取这个配置文件
export LD_LIBRARY_PATH = ./ (配置动态链接库目录)
这样配置完每次打开终端都生效
动态库的命名:
Realname: libc-2.19.so
这是一个软连接
Linkername : libc.so
Soname:
libc.so.6
6是大版本号
Soname的作用 :
当前是libc-2.19.so
官方进行更新后
可能变成libc-2.20.so
随着版本更新 版本更新的记录不想让用户知道
防止用户引起恐慌..
所以使用soname
Soname存在意义就是隐藏内部实现细节
静态库)
nm app:
Printf mul都没实现
nm app1:
Mul是已经实现的
07 gdb调试
编译的时候 加 -g 参数
gdb app
list 1 从第一行开始往后列
b 20
info b
条件断点
disable
run
p I (print i
S (step 单步向下执行
display
n next
s step
当定义到一个函数的时候就有区别了
Next会跳过函数 step会跳入函数
ptype
栈帧:
函数调用会在栈上进行存储
栈帧:保存局部变量和临时值
局部变量
临时值:
例:
函数执行一半执行到mul函数 mul函数执行完了 要回到刚才的位置 所以刚才的位置的地址要保存一下 这个就是临时值
函数只要调用就产生栈帧
当main函数开始调用时 产生一片栈帧,
执行第一个内部的函数时候 在main下面产生一个栈帧
当这个函数执行完毕后 这个栈帧消失
下一个内部函数栈帧生成在main栈帧下面…
Bt
发现两块栈帧
Info locals 查看当前栈帧的值
段错误 直接Run
直接运行 然后停止在段错误的代码
08-makefile_x264
Vi makefile
Vi Makefile
只能起这两个名字 才能使用默认的make命令去执行它
Makefile里都是一组一组的规则
规则包含三部分:
目标 : 生成目标需要的依赖
如何生成目标
App: add.c sub.c mul.c main.c
gcc add.c sub.c mul.c main.c
Make
比如一个main.c有三个依赖,我只修改了一个依赖 我不希望每次都把所有.c都编译
这时候可以使用makefile
Makefile:
app: add.o sub.o mul.o main.o
gcc add.o sub.o mul.o main.o -o app
add .o: add.c
gcc -c add.c -o add.o
sub.o: sub.c
gcc -c sub.c -o sub.o
mul.o: mul.c
gcc -c mul.c -o mul.o
main.o:main.c
gcc -c main.c -o main.o
然后我修改一个依赖
然后make , makefile会智能地只编译修改过的c文件
.c(依赖)的修改时间比.o(目标)的修改时间晚, 所以需要重新生成目标
重新生成目标后add.o 的修改时间比app晚 所以需要重新生成目标
然后 make clean
-n 命令 查看执行make的话会做什么
make clean -n
自动变量
$@
$<
$^
(当$< 和$^ 都可以用的时候 建议用$< 因为后边会用它写模式规则)
第三个参数中包含第一个参数的部分替换为第二个参数
补充小知识:
%也是通配符
现在就可以 向里面加.c 调整.h 而不用调整makefile了
make clean 因为clean得依赖修改时间没有变化(没有依赖)
所以会提示没有更新
解决方法:
.PHONY: clean
把clean 声明称尾目标 不管依赖条件满不满足都会去执行它
小技巧 rm前面加-
-rm
意思是无论是否出错 后序命令都正常执行
因为有时候rm遇到无法删除得文件报错了 后面就都删除不了了
当文件不叫makefile得时候要用-f指定
make –f xxxx
make默认第一条规则是终极目标 如果第一个是完成了 就不往下执行了
如果想随便掉换行需要指定终极目标
ALL:app 放在最开始
模式规则:
静态模式规则:
最终版:
通常的项目目录