2017-2018-1 20155313 《信息安全系统设计基础》第五周学习总结
课堂笔记
宿主机(x86):linuxhello >gcc
目标机->实验箱:armhello >arm-gcc
交叉编译
程序->进程。
操作系统:并发的系统。硬件:CPU,内存,IO设备
linux、unix操作系统:输入输出被放在操作文件中。
操作系统:虚拟内存、进程、文件
nfs 宿主机ip/d /d
>man -k
>grep -nr
教材学习
1.程序编码
一个C语言程序需要经过四个阶段才能变成一个可执行的二进制代码。
- 预处理阶段:预处理器cpp根据编译文件以“#”开头的命令,读取系统头文件stdio.h(.h结尾的表示头文件,.c表示可执行文件)的内容,并把它插入到程序文本中,得到一个新的文件。
- 编译阶段:编译器ccl将预处理后的文件翻译成.s结尾的文本文件,里面包含一个汇编程序。(linux命令:gcc -Og -s hello.c)
- 汇编阶段:汇编器ss将汇编 程序翻译成二进制的机器语言,并把结果保存在以.o结尾的二进制文件中。(linux命令:gcc -Og -c hello.c)
- 链接阶段:链接器ld将程序用到的C语言类库的函数汇编后的代码合并到hello.o,得到可执行的目标文件。(linux命令:gcc -o hello hello.c)
- 对二进制文件进行反编译:objdump -d hello.o
2.数据格式
- 由于是从16位体系结构扩展成32位,intel用术语字(word)表示16位数据类型,因此32位为双字(double words),64位数为4字(quad words)。
- 以下是比较容易模糊的数据类型大小:
32位机上:float 4 long int 4 double 8 longlong 8 char* 4 unsigned long 4
64位机上:float 4 long int 8 double 8 longlong 8 char*8 unsigned long 8
另外,GCC 用long double表示扩展精度(10字节),出于存储器性能考虑,会被存储为12字节
3.访问信息
操作数指示符
大多数指令有一到多个操作数,操作数有三种:
- 立即数:即常数值
- 寄存器:表示某个寄存器内容
- 存储器引用:根据计算出来的地址(通常称有效地址)访问某个存储器位置
因此寻址方式也有多种,如:立即数寻址、寄存器寻址、绝对寻址、间接寻址、变址寻址、伸缩化的变址寻址。
数据传送指令
几个重要数据传送指令:mov族(之所以称这为族是因为mov指令还有很多兄弟指令如movb、movw、movsb、movzb,这是我个人对它们的称呼,便于记忆mov其他几个比较低调的兄弟)、pop、push。
另外,对于mov族,movb、movw自不必做过多解释,movsb、movzb分别为符号扩展、零扩展,它们只拷贝一个字节,源操作数均为单字节,并设置目的操作数中其余的位,效果如下:
初始假设:%dh=8D %eax=98765432
- 1.movb %dh,%al;%eax=9876548D
- 2.movsbl %dh,%eax;%eax=FFFFFF8D(目的操作数高24位设为源字节最高位,在这里为很显然为1,所以前24位为全F)
- 3.movzbl %dh,%eax;%eax=0000008D(目的操作数高24位被设为0)
对于pushl指令等价于:
subl $4,%esp
movl %ebp,(%esp) //注意这里的括号引起的差别
popl指令等价于:
movl (%esp),%eax
addl $4,%esp
4.控制
循环
C语言提供了多种循环结构,即do-while、while和for。汇编中用条件测试和跳转结合起来实现。大多数汇编器根据一个循环的do-while形式来产生循环代码,即使do-while的形式用得相对较少。其他的循环会首先转换成do-while形式,然后再编译成机器代码。首先从do-while开始。
do-while循环
do-while的通用形式可以翻译成如下所示的条件和goto语句:
loop:
body-statement
t=test-expr;
if(t)
goto loop;
每次循环,程序会执行循环体内的语句,然后执行测试表达式。如果测试为真,则回去再执行一次循环。
while循环
将while循环翻译成机器代码有很多种方法,常见的是使用条件分支,在需要时省略循环体的第一次执行,从而将代码转换成do-while循环,如下:
if(!test-expr)
goto done;
do
body-statement
while (test-expr);
done:
接下来,这个代码可以直接翻译成goto代码,如下:
t=test-expr;
if(!t)
goto done;
loop:
body-statement
t=test-expr;
if(t)
goto loop;
done:
for循环
for循环可以很容易转换成while循环,进而转换成do-while形式:
init-expr;
if(!test-expr)
goto done;
do {
body-statement
update-expr;
} while (test-expr);
done:
然后,将它转换成goto代码:
init-expr;
t=test-expr;
if(!t)
goto done;
loop:
body-statement
update-expr;
t=test-expr;
if(t)
goto loop;
done:
代码调试中的问题和解决过程
- 问题1:
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 20篇 | 400小时 | |
第一周 | 100/100 | 1/1 | 5/5 | |
第二周 | 100/200 | 2/3 | 5/10 | |
第三周 | 100/300 | 2/5 | 5/15 | |
第四周 | 100/400 | 1/6 | 5/20 |