教材学习内容总结
-
X86 寻址方式的变化,经历三代:
1-DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
2-8086的分段模式
3-IA32的带保护模式的平坦模式
-
gcc -S xxx.c 可以得到C语言编译器产生的汇编代码,但不会做其他工作,也可以用objdump -d xxx 反汇编; 注意函数前两条和后两条汇编代码,所有函数都有,建立函数调用栈帧,应该理解、熟记。使用“-c”命令,GCC就会编译并汇编该代码,得到二进制文件XXX.o。由此可见,机器执行的实际上是对一系列指令进行编码的字节序列。
-
64位机器上想要得到32代码:gcc -m32 -S xxx.c
-
MAC OS中没有objdump, 有个基本等价的命令otool
-
Ubuntu中 gcc -S code.c (不带-O1) 产生的代码更接近教材中代码(删除"."开头的语句)
-
二进制文件可以用od 命令查看,也可以用gdb的x命令查看。
有些输出内容过多,我们可以使用 more或less命令结合管道查看,也可以使用输出重定向来查看:
od code.o | more
od code.o > code.txt -
Linux和的汇编格式为ATT格式,而Windows的为Intel格式。二者在语法上有区别——后者省略了指示大小的后缀、寄存器前的%等。
-
gcc -S 产生的汇编中可以把 以”.“开始的语句都删除了再阅读
-
寻址方式的通用公式:
有效地址可以表示为Imm+R[Eb]+R[Ei]*s。
Imm为立即数偏移;Eb为基址寄存器;Ei为变址寄存器;s为比例因子。如:1.Ea——操作数值:R[Ea]
2.(Ea)——操作数值:M(R[Ea])
3.Imm(Ea)——操作数值:M(Imm+R[Ea])
-
理解操作数的三种类型:立即数、寄存器、存储器——立即数(不超过32位的数值)、寄存器(用Ea表示任意寄存器a,R[Ea]表示它的值)、存储器(会根据计算出来的地址访问某个内存,用M[addr]表示);掌握有效地址的计算方式 Imm(Eb,Ei,s) = Imm + R[Eb] + R[Ei]*s
-
MOV相当于C语言的赋值”=“,注意ATT格式中的方向, 另外注意不能从内存地址直接MOV到另一个内存地址,要用寄存器中转一下。
-
push,pop语句:
1.push:把数据压入栈中;
2.pop:删除数据。
3.栈遵循“后进先出”的原则,且栈顶向下增长;在栈指针%esp中保存着栈顶元素的指针。
-
for循环的流程:程序首先对初试表达式init-expr求值,然后进入循环;在循环中它先对测试条件test-expr求值,如果为假则退出循环否则执行循环体;最后对更新表达式求值。
-
switch语句根据一个整数索引值进行多重分支;通过使用跳转表使其更加高效。跳转表是一个数组,表项i是一个代码段地址(C语言用&表示一个指向数据值的指针;而&&表示一个指向代码位置的指针)
-
leal,加载有效地址;将数据从存储器读到寄存器
1.NEG,取负
2.SUB S,D,将D-S的结果送至D
3.移位操作 SAL,SHL,SAR,SHR的移位量可以是立即数或%cl中的数
教材学习中的问题和解决过程
代码托管
结对及互评
点评模板:
- 博客中值得学习的或问题:
- xxx
- xxx
- ...
- 代码中值得学习的或问题:
- xxx
- xxx
- ...
- 其他
本周结对学习情况
- [结对同学学号1](博客链接)
- 结对照片
- 结对学习内容
- XXXX
- XXXX
- ...
其他(感悟、思考等,可选)
xxx
xxx
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 2/2 | 5/5 | |
第二周 | 100/100 | 3/4 | 10/15 | |
第三周 | 100/200 | 4/5 | 20/35 | |
第四周 | 200/400 | 2/7 | 25/60 | |
第五周 | 1000/1400 | 2/9 | 35/95 | |
第六周 | 300/1700 | 3/12 | 50/135 | |
第七周 | 200/1900 | 2/14 | 45/180 |