2019-2020-1 20175316 《信息安全系统设计基础》第3周学习总结
教材学习内容总结
X86 寻址方式经历了一下三代:
DOS时代的平坦模式,不区分用户空间和内核空间,很不安全。
8060的分段模式
IA32的带保护模式的平坦模式
程序编程:
gcc -01 -o p p1.c
1.-01 表示使用第一级优化。优化的级别与编译时间和最终产生代码的形式都有关系,一般认为第二级优化-02 是较好的选择。
2.-o 表示将p1.c编译后的可执行文件命名为p
代码示例
long mult2(long,long);
void multstore(long x, long y, long *dest) {
long t = mult2(x, y);
*dest = t;
}
在命令行上使用-S选项,就能看到C语言编译器产生的汇编代码:
# gcc -Og -S mstore.c
这会使GCC运行编译器,产生一个汇编文件mstore.c,但是不做其他进一步的工作。汇编代码文件包含各种声明,包括下面几行:
multstore:
pushq %rbx
movq %rdx, %rbx
call mult2
movq %rax, (%rbx)
popq %rbx
ret
上面的代码中每个缩进去的行都对应于一条机器指令。比如pushq指令表示应该将寄存器%rbx的内容压入程序栈中。这种代码中已经除去了所有关于局部变量名或数据类型的信息。
如果我们使用-c命令行选项来编译并汇编该代码:
# gcc -Og -c mstore.c
# ll
total 637312
……
-rw-r--r-- 1 root root 1368 Aug 7 14:59 mstore.o
……
这就会产生目标代码文件mstore.o,它是二进制格式的,所以无法直接查看。1368字节的文件mstore.o中有一段14字节的序列,它的十六进制表示为:
53 48 89 d3 e8 00 00 00 00 48 89 03 5b c3
这就是上面列出的汇编指令对应的目标代表。从中可以得到一个信息,即机器执行的程序只是一个字节序列,它是对一系列指令的编码。机器对产生这些指令的源代码几乎一无所知。
要查看机器代码文件的内容,有一类称为反汇编器的程序非常有用。这些程序根据机器代码产生一种类似于汇编代码的格式。在Linux系统中,带'-d'命令行标志的程序OBJDUMP(表示“object dump”)可以充当这个角色:
# objdump -d mstore.o
mstore.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <multstore>:
0: 53 push %rbx
1: 48 89 d3 mov %rdx,%rbx
4: e8 00 00 00 00 callq 9 <multstore+0x9>
9: 48 89 03 mov %rax,(%rbx)
c: 5b pop %rbx
d: c3 retq
机器级编程的两种抽象
-
指令集结构ISA
是机器级程序的格式和行为,定义了处理器状态、指令的格式,以及每条指令对状态的影响。 -
机器级程序使用的存储器地址
是虚拟地址看上去是一个非常大的字节数组,实际上是将多个硬件存储器和操作系统软件组合起来。
执行汇编命令:gcc –s xxx.c –o xxx.s
反汇编命令:objdump –d xxx
64位处理器得到32代码的命令:gcc –m32 –s xxx.c
访问信息
1.三种操作数:立即数、寄存器、存储器
2.数据传送指令:
栈的特点
a、 遵循“后进先出”的原则
b、 push压栈,pop出栈
c、 栈顶:总是从这端插入和删除元素
d、 栈顶元素的地址是最低的
e、 栈指针%esp保存着栈顶元素的地址
1.数据传送示例:
局部变量通常保存在寄存器中;
寄存器访问比存储器访问要快的多。
算术和逻辑操作
1.四组操作:
-
加载有效地址:将有效地址写入目的操作数,目的操作数必须是寄存器。
-
一元操作:只有一个操作数,可以是寄存器也可是存储器位置。
-
二元操作:源操作数是第一个,可以是立即数、寄存器、存储器 ;目的操作数是第二个,可以是寄存器、存储器;两个不能同时为存储器。
1.特殊的算术操作
控制
2.条件码
CF:进位标志
ZF:零标志
SF:符号标志
OF:溢出标志
1.循环结构的三种形式:
do-while:先执行循环体语句,再执行判断,循环体至少执行一次。
while: 把循环改成do-while的样子,然后用goto翻译
for: 把循环改成do-while的样子,然后用goto翻译
过程
1.栈帧结构:机器用栈来传递过程参数、存储返回信息、保存寄存器用于以后恢复,以及本地存储。为单个过程分配的那部分栈称为栈帧。
最顶端的栈帧以两个指针界定,寄存器%ebp为帧指针,寄存器%esp为栈指针。
2.转移控制:call指令、ret指令、leave指令
3.寄存器使用惯例:
%eax,%edx,%ecx 调用者保存寄存器
%ebx,%esi,%edi 被调用者保存寄存器
%ebp,%esp 保持寄存器
教材学习中的问题和解决过程
问题1:程序的可移植性问题。
-
问题1解决方案:在假期学习C的过程中也碰见过这个问题,但是只是了解了一下,前两天又碰见了这个名词,在这次看书的过程中又看见了这个词,感觉很重要就深入的学习了一下。
问题2:汇编语言的不熟悉,不会用
-
问题2解决方案:多加联系
上周考试错题总结
无
其他(感悟、思考等,可选)
- 这两周学习了一个全新的概念,汇编语言的使用,我感觉自己的学习还不够努力,比如一些基本命令movl等不了解什么意思,需要多加背诵并练习。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 300/500 | 2/4 | 18/38 | |
第三周 | 500/1000 | 3/7 | 22/60 |