教材学习内容总结
书上有的内容我就不重复赘述了,只需要将部分重要的知识点归纳总结一下。
1.使用GDB的堆栈跟踪功能(GDB中有很多针对调用堆栈的命令,都需要一个目标栈帧,例如打印局部变量值的命令)
- 在栈帧之间切换
frame args 将当前栈帧设置为args(编号或Address)指定的栈帧,并打印该栈帧的简要信息。
up n 向上回退n个栈帧(更外层),n默认为1.
down n 向下前进n个栈帧(更内层),n默认为1.
- 打印栈帧信息(不移动栈帧)
frame 打印当前栈帧的简要信息。
info frame 打印当前栈帧的详细信息。
info frame args 打印指定栈帧的详细信息。
info args 打印函数参数信息。
info locals 打印当前可访问的局部变量的信息。
- 打印调用堆栈
backtrace 打印全部栈帧的简要信息,按Ctrl-c可终止打印。
backtrace n 打印最内层的n个栈帧的简要信息。
backtrace -n 打印最外层的n个栈帧的简要信息。
backtrace full 打印全部栈帧的详细信息。
backtrace full n 打印最内层的n个栈帧的详细信息。
backtrace full -n 打印最外层的n个栈帧的详细信息。
- gdb相关使用指令
2.gcc -S xxx.c -o xxx.s 可以获得汇编代码
3.反汇编的两种形式:gcc -S xxx.c或者objdump -d xxx.o
4.二进制文件可以用od 命令查看,也可以用gdb的x命令查看。 有些输出内容过多,我们可以使用 more或less命令结合管道查看,也可以使用输出重定向来查看
od code.o | more
od code.o > code.txt
5.esi edi可以用来操纵数组,esp ebp用来操作栈帧。 对于寄存器,特别是通用寄存器中的eax,ebx,ecx,edx,32位的eax,16位的ax,8位的ah,al都是独立的
6.不能从内存地址直接MOV到另一个内存地址,要用寄存器中转一下。能区分MOV,MOVS,MOVZ,掌握push,pop,栈顶元素的地址是所有栈中元素地址中最低的,局部变量保存在寄存器中
7.有条件跳转的条件看状态寄存器(教材上叫条件码寄存器) ,leal不改变条件码寄存器
8.CMP不改变原数,只需要知道数据之间的关系;SUB用在需要得到两个数据进行相减后的结果; SET指令根据t=a-b的结果设置条件码
9.操作数三种类型:a.立即数;b.寄存器Ea表示寄存器a,R[Ea]表示它的值;c.存储器Mb[Addr]表示对存储在存储器中从地址Addr开始的b个字节值的引用。 有效地址Imm(Eb,Ei,s)=Imm+R[Eb]+R[Ei]*s(s为1、2、4、8)
10.数据传送指令MOV S,D(将S中的字节传送到D) MOVS(符号扩展),MOVZ(零扩展)不能直接从存储器到存储器,需寄存器中转。
11.栈是向下增长的,栈顶元素的地址是所有栈中元素地址中最低的,栈指针%esp保存着栈顶元素的地址。
学习过程
1.实验楼中的code.c源代码及汇编代码。最开始用gcc编译的时候,命令行没有显示结果,我感到很奇怪,后来才发现是因为没有输出函数。(太大意了!)经过细微修改后,运行如下:
将含有代码中以"."开头的编译器指令删除后的结果:
2.反汇编的两种形式:objdump -d xxx.o或者gcc -S xxx.c
3.使用gdb的bt/frame/up/down指令动态查看调用线帧的情况
4.书上作业3.22
- 题目:while循环中基于汇编语言,填写 C语言空缺
- 解决方法:先一步步将汇编语言读懂,在不熟练的情况下查之前的表格,知道testl为测试;je跳转条件为等于零或相等;shrl为右移;or为异或;jne为跳转条件不等于零,了解执行过程后,就很好去填写C语言中缺失的部分了。
- 这个代码计算参数x的奇偶性。如果x中有奇数个1,就返回1,;如果有偶数个1,就返回0,查看汇编文件:
5.书上作业3.23
- 题目:for循环中基于汇编语言,填写 C语言空缺
- 解决方法:这个循环比上一个更为复杂,应该根据for循环的特性慢慢分析。
- 这段代码把x中的位反过来,创造一个镜像。实现的方法是:将x的位从左往右移,然后再填入这些位,就像是把val从右往左移。查看汇编文件:
6.书上作业3.29
- 题目:switch中基于汇编语言,填写 C语言空缺
- 解决方法:关键是将来自汇编代码和跳转表的信息结合起来,理清不同情况
- 查看汇编代码:
代码托管情况
把所有的代码都增加了详细的注释:
代码统计行数:
心得体会
本周主要是对于汇编的学习,由于之前对汇编的学习不系统,理解得也不够透彻,所以本周的学习还是相对有一些吃力的,虽然3.1到3.6的内容大部分都相当于在复习,但是做题的时候,看到一些指令还是要返回到前面翻书查看指令的具体用法。本周的学习内容本来也很多,不过根据娄老师给的教材重点,有目的有重心的去看教材,已经减轻很大负担了。不过完全不看教材,一心想走捷径是绝对不行的,这门课本身就需要耗费大量时间来消化。从最开始看教材,熟悉知识点,到看代码,理解代码,到最后自己能调试代码,自己能编写代码。必须得静下心来,投入大量精力与时间,将理论与实践相结合,才能学出效果。任何一门学科都有自身的特点,将其特点与自身的学习风格相结合,打造出一套适合自己的完美学习方法,这至关重要,现在凡事都要讲科学,毫无疑问运用科学的学习方法,学习效率必定大大提高,还能有效的节约时间。何乐而不为?
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 1/2 | 20/20 | |
第二周 | 58/58 | 1/3 | 20/40 | |
第三周 | 150/208 | 1/4 | 22/62 | |
第五周 | 150/358 | 1/5 | 21/83 |