20145331 《信息安全系统设计基础》第5周学习总结
教材学习内容总结
3.2
1、产生汇编代码(机器级代码):gcc -s xxx.c -o code.s ,另外,反汇编代码中以“.”开头的是指导汇编器和链接器的命令,省略不看。
2、汇编一个代码:gcc -c code.c -o code.o,产生的code.o是一个二进制格式文件,用od code.o命令查看。
3、反汇编:objdump -d code.o(对象也可以是可执行文件code),产生的反汇编代码省略了大小指示符。
4、intel代码省略了指示大小的后缀、寄存器名字前面的%,用不同的方式描述存储器中的位置(如[ebp+4]),包含多个操作数时顺序相反。
3.3
1、1字(b)8位,1字(w)16位,双字(l)32位;IA32不支持64位整数运算。
3.4
1、三类操作数:立即数、寄存器、存储器位置。$Imm是立即数,Imm是存储器,Ea是寄存器,(Ea)是存储器。
2、“mov”指令和“=”用法相同,movs符号扩展,movz零扩展。传送指令两个操作数不能都指向存储器位置。
%dh=CD %eax=98765432
movb %dh %al %eax=987654CD
movsbl %dh %eax %eax=FFFFFFFFCD
movzbl %dh %eax %eax=00000000CD
传哪个改哪个,寄存器其余三字节不变。
3、压栈pushl, 弹出popl;栈遵循后进先出原则,栈顶地址最低。
3.5
指令很多,很好理解,感觉这几个比较重要: 1、加载有效地址:leal S,D:把S的地址给D。D必须是寄存器。
2、减法:SUB S,D:D=D-S。
3、操作数类型:
一元操作的操作数可以是:寄存器+存储器位置。
二元操作的源操作数可以是:立即数+寄存器+存储器位置;目的操作数可以是:寄存器+存储器位置。(两种操作数不能都是存储器位置)
4、移位操作:移位量为单字节,可以是立即数或单字节寄存器元素%cl(只能是这个寄存器)。
3.6
1、条件码:单个位。
2、cmp(根据操作数的差设置条件码)、test指令只改条件码不改寄存器。
3、set指令操作数大小为单字节,得32位结果要对高24位清零。
4、跳转指令编码方法:目标指令地址-跳转指令后面那条指令得地址=编码。
5、goto代码:就是把汇编代码按顺序用c语言写出来,碰到跳转指令用goto。
6、c语言中的所以循环结构先转化为do-whlie结构,再转化为汇编代码。
3.7
1、call:返回地址压栈,跳转到被调用过程起始处。
2、ret:弹出返回地址,并跳转到这个位置。
3:%ebp帧指针、%esp栈指针。
4、p调用q,q的参数放在p的栈帧中,q的栈帧要保存其他寄存器的值等。
5、寄存器eax、edx、ecx为调用者保存寄存器,ebx、esi、edi为被调用者保存寄存器。
6、最后附上函数调用时栈帧得结构变化图:
gdb调试
P175的表格很重要,有些之前用到过。
教材学习中的问题和解决过程
1、P128,不明白第一条跳转指令的编码为啥是OxD,没有看懂,3.15习题不会做。
看了别人的博客,搞明白了,目标指令地址-跳转指令后面那条指令得地址=编码,用的就是这个公式。跳转命令后面的就是目标地址,指令前后两个字节就是编码。
2、P155习题3.33第三问中x、y的存放地址-4(%ebp)、-8(%ebp),这两个地址是固定的么?就是说系统默认它们永远都是存放在保存的%ebp下面么,可不可以在其他栈帧中未使用的字节空间去存它们?书上只是说它们都是相对于帧指针存的但并没有说存哪。
代码调试中的问题和解决过程
P153~P155代码一开始看不明白,结合前面的栈帧结构图反复看,并结合P175的表格,用gdb输出各个寄存器的内容后,明白了函数调用栈帧的过程:
caller:
pushl %ebp //保存%ebp
movl %esp,%ebp //设置新的帧指针为旧的栈指针
subl $24,%esp //分配24字节的栈空间
movl $534,-4(%ebp)
movl $1057,-8(%ebp)
leal -8(%ebp),%eax //计算arg2的地址放入寄存器中,也就是&arg2。(leal操作数必须为寄存器!)
movl %eax,4(%esp) //将&arg2存入栈
leal -4(%ebp),%eax
movl %eax,(%esp) //同
call swap_add //调用函数,返回地址压栈。
一共有24字节的空间,存数据用了4+4=8字节,地址同样8字节,还有8字节未使用。
swap_add:
...
//传参过程:swap_add的参数全部存在caller的栈帧里。
movl 8(%ebp),%edx//原来是0,保存的%ebp,+4;返回地址,+4;所以为+8.
movl 12(%ebp),%ecx//8+4=12
movl (%edx),%ebx
movl (%ecx),%eax
movl %eax,(%edx)
.....
addl %ebx,%eax//返回值在%eax中。
...
这段代码我还是有问题:在传参时已经传的是地址了,为什么第一行代码movl 8(%ebp),%edx的作用是get xp而不是get *xp?也就是说: 8(%ebp)里的东西为什么不能直接是%ebx里的东西?
课后作业中的问题和解决过程
1、P113练习3.1刚开始看题就晕了,很多操作数搞混了,仔细看了表格后,明白了:$Imm是立即数,Imm是存储器位置,Ea是寄存器,(Ea)是存储器位置;此外,比例因子只和变址寄存器的值相乘,最后总结答案如下:
Ox100
OxAB
Ox108
OxFF
OxAB(和第二个等价)
Ox11
Ox13
OxFF
Ox11
2、P155练习3.32题不会做,反复阅读P153~P154后,发现漏看了返回值放在%eax寄存器中这句话,很关键,解答思路如下:
1、代码最后两行:
subl %eax,%edx
movl %edx,%eax
以及return x-c,可确定:%edx为x,%eax为c,注意到有后缀“l”,所以c和x为long int型。
2、看前两行,movsbl、movl命令说明%edx、%eax为双字,第三行代码明显是*p=d,所以,%edx为d,%eax为p,全部为long int型。
3、完整c代码如下:
long int fun(long int d,long int p)
{
*p=d;
long int c=p;
long int x=d;
return x-c
}
//不知道对不感觉上差不多是它。
本周代码托管
本周新建了项目,以后代码不用传到java项目里了:
https://git.oschina.net/20145331/wsc20145331_linux.git
其他(感悟、思考等,可选)
看goto代码时感觉把c的循环和分支结构掌握的更好了;把上学期的汇编重学了一遍,感觉这本教材水平很高,一看就会,上学期的汇编课本啥都看不懂;知识很多,写个博客感觉复习了一遍,把调用栈帧的概念和ISA指令体系结构中的细节把握得更准确了,感觉写博客还是有用的。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 140/310 | 1/5 | 50/100 | 基本看得懂汇编代码 |