c、linux学习笔记

713 查看

linux命令

统计相关

find . -name *.c | wc -l                     //查找并统计c程序文件的个数
find . -name *.c -exec wc {} -l \;           //查找并统计每个C程序的行数
find . -name *.c -exec cat {} \; | wc -l     //查找并统计所有c程序的总行数

编译分析

gcc simple.c -o simple                       //编译生成为指定文件,默认为a.out
gcc -S simple.c                              //生成 simple.s 的汇编程序 
gcc -E print.c > print.i                     //预处理,头文件的引入与处理
gcc -v print.c                               //生成编译链接过程,libc.a
cc1                                          //编译器
as                                           //汇编器
collect2                                     //链接器
objdump -d a.out                             //得到所有机器指令(反汇编)

echo $?                                      //上一个程序执行后的返回值
objcopy -O binary -j .text a.out text.bin    //提取可执行文件的代码
objcopy -O binary -j .data a.out data.bin    //提取可执行文件的数据 

file a.out                                   //文件格式(类型)信息
hexdump -C a.out                             //查看二进制文件的内容
readelf -a a.out                             //分析ELF文件

ps aux | grep a.out

C语言知识

代码段和数据段

局部变量的数据分配在栈上,且赋值操作会被解析成指令;全局变量分配在数据区,赋初值的等号相当于冒号,并不解析成指令。

物理地址与虚拟地址

&local = 0xbfb8948c
&global = 0x804a018
main = 0x8048414
_start is 0x8048360                             //c语言真正的入口

直观映像,内存跨度 128M ~ 3G 。
操作系统管理物理内存,每个进行都有独立的内存空间,程序打印的地址都是虚拟地址,其对应关系由操作系统内核管理。

extern _start;                                 //由链接器生成的
...
printf("_start is %p\n", &_start);

调试宏

#define PRINT(x)    printf("<debug>" #x "= %d\n", x)
//#define PRINT(x)

条件编译;-lm 链接时加入数学库

#if DEGUG
    …
#endif

$ gcc t.c -lm -DDEBUG        //定义
$ gcc t.c -lm -UDEBUG        //不定义

用来交换变量的宏,do...while的经典应用,注意两个关键点

#define SWAP(a,b)        \
do{                        \
    char tmp;            \
    tmp = b;            \
    b = a;                \
    a = tmp;            \
}while(0)                        //故意不要语法要求的分号

if(j >= 0)
    SWAP(x, y);
else                            //else前面原本是不应该有分号的
    print("error\n");