2017-2018-1 学号20155209 《信息安全系统设计基础》第五周学习总结
教材学习内容总结
- ISA:指令集体系结构,机器级程序的指令和格式。它定义了处理状态,指令的格式,以及每条指令对状态的影响。
-
- IA32 指令长度从1到15个字节不等。常用的指令以及操作数较少的指令所需的字节数少,而那些不太常用或者操作数较多的指令所需的字节数较多。
- 设计指令格式的方式是,从某个给定位置开始,可以将字节唯一地解码成机器指令。如,只有pushl %ebp 是以字节值55开头。
- 反汇编器只是基于机器代码文件中的字节序列来确定汇编代码。
- GCC采用的是AT&T的汇编格式, 也叫GAS格式(Gnu ASembler GNU汇编器), 而微软采用Intel的汇编格式。
- 因为在许多机器上, 32位数都称为长字(long word), 这是沿用以16位字为标准的时代的历史习惯造成的.
如果没有指定操作数长度的话,编译器将按照目标操作数的长度来设置。比如指令“mov %ax, %bx”,由于目标操作数bx的长度为word,那么编译器将把此指令等同于“movw %ax, %bx”。同样道理,指令“mov $4, %ebx”等同于指令“movl $4, %ebx”,“push %al”等同于“pushb %al”。对于没有指定操作数长度,但编译器又无法猜测的指令,编译器将会报错,比如指令“push $4”。 - 2个变址和指针寄存器(ESI和EDI),
32位CPU有2个32位通用寄存器ESI和EDI。其低16位对应先前CPU中的SI和DI,对低16位数据的存取,不影响高16位的数据。 - 2个重要的指针寄存器(ESP和EBP).从计算机科学的角度看,栈是一种数据结构,是一种先进后出的数据表。栈的最常见操作有两种:Push(入栈)和Pop(出栈)。
- 一个 IA32中央处理单元CPU包含一组8个存储32位值的寄存器,用来存储整数数据和指针,名字都以%e开头。
- movb、movsbl和movzbl之间的差别如下:假设%dh =8D,%eax=98765432 movb %dh ,%a1 %eax=9876548D movsbl %dh , %eax %eax=FFFFFF8D movzbl %dh,%eax %eax=0000008D 在以上的例子中都是将寄存器%eax 的低位字节设置为%edx 的第二个字节。movb指令不改变其他三个字节。根据原字节的最高为,movsbl指令将其他三个字节设为全1或全0。movzbl指令无论如何都是将其他三个字节设为全0。
- pushl 与popl是用来将数据压入栈中和从栈中弹出数据的。它们两个的指令都只有一个操作数,即它们所要压入或者弹出的数据。将一个双字值压入栈中,首先要将栈指针减4,然后将值写入到新的栈顶地址。弹出一个双字的操作是从栈顶位置读出数据,然后将栈指针加4。
- 加载有效地址指令leal实际上是movl指令的变形。它的指令形式是从存储器读数据到寄存器,但实际上它根本就没有引用存储器。
- 一元操作即只有一个操作数,二元操作即是有两个操作数。
- 位移操作,先给出位移量,然后是待移位的值。可以进行算术和逻辑右移。
- CPU包含了一组单个位的条件码寄存器,它们描述了最近的算术或逻辑操作的属性。常见的条件码为:进位标志(CF)、零标志(ZF)、符号标志(SF)、溢出标志(OF)
- 两种最常用的访问的条件码的方法不是直接读取它们,而是根据条件码的某个组合,设置一个整数寄存器或是执行一条分支指令。每个指令根据条件码的某个组合,将一个字节设置为0或者1。同一个机器指令可以有不同的名字。
- 一个过程调用包括将数据(以过程参数和返回值的形式)和控制从代码的一部分传递到另一部分。另外,它还必须在进入时为过程的局部变量分配空间,并在退出时释放这些空间。
教材学习中的问题和解决过程
(一个模板:我看了这一段文字 (引用文字),有这个问题 (提出问题)。 我查了资料,有这些说法(引用说法),根据我的实践,我得到这些经验(描述自己的经验)。 但是我还是不太懂,我的困惑是(说明困惑)。【或者】我反对作者的观点(提出作者的观点,自己的观点,以及理由)。 )
- 问题1:汇编语言里的寄存器分别有什么功能,都应该怎样使用。
- 问题1解决方案:
- EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。
- EBX 是"基地址"(base)寄存器, 在内存寻址时存放基地址。
- ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。
- EDX 则总是被用来放整数除法产生的余数。
- ESI/EDI 分别叫做"源/目标索引寄存器"(source/destination index),因为在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串.
- EBP 是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer). 在破解的时候,经常可以看见一个标准的函数起始代码:
push ebp ; 保存当前ebp
mov ebp,esp ; EBP设为当前堆栈指针
sub esp, xxx ; 预留xxx字节给函数临时变量.
..
这样一来,EBP 构成了该函数的一个框架, 在EBP上方分别是原来的EBP, 返回地址和参数. EBP下方则是临时变量. 函数返回时作 mov esp,ebp/pop ebp/ret 即可.
- ESP 专门用作堆栈指针,被形象地称为栈顶指针,堆栈的顶部是地址小的区域,压入堆栈的数据越多,ESP也就越来越小。在32位平台上,ESP每次减少4字节。
- 参考资料
- 问题2:给出的地址计算方式Imm(Eb,Ei,s) = Imm + R[Eb] + R[Ei]*s,应该如何理解。
- 问题2解决方案:
- 对于寻址方式的理解:
- 寻址方式就是寻找操作数或操作数地址的方式。8086提供了与操作数有关和与I/O端口地址有关的两类寻址方式。与操作数有关的寻址方式有七种,分别是立即寻址,寄存器寻址,直接寻址,寄存器间接寻址,寄存器相对寻址,基址加变址寻址,相对基址加变址寻址;与I/0端口有关的寻址方式有直接端口寻址和间接端口寻址方式。另外还有隐含寻址,即把要寻找的地址包含在操作码中。
- 公式各值分析:
- 立即数(imm,常数值),在 ATT 格式的汇编中,书写方式是‘$’ 后面跟一个用标准 C 表示法表示的整数。
- 寄存器,它表示某个寄存器的内容。用符号Ea来表示任意寄存器 a,用引用 R[Ea] 来表示它的值,这是将寄存器集合看成一个数组 R,用寄存器标识符作为索引。
- 存储器引用,它会根据计算出来的地址(通常称为有效地址)访问某个存储器位置。因为将存储器看成一个很大的字节数组,用符号Mb[Addr]表示对存储在存储器中从地址Addr 开始的 b 个字节值的引用。为了方便,通常省去下方的 b。
- 使用方式:
- 底部用语法 Imm(Ea, Eb, s) 表示的是最常用的形式。这样的引用有四个组成部分:一个立即数偏移 Imm, 一个基址寄存器 Eb , 一个变址寄存器 Ei和一个比例因子 s,这里 s 必须是 1、 2、 4 或者 8。然后,有效地址被计算为 Imm + R[] + R[] * s。应用数组元素时,会用到这种通用形式。其他形式都是通过通用形式的特殊情况,只是省略了某些部分。当引用数组和结构元素时,比较复杂的寻址模式是很有用的。
代码调试中的问题和解决过程
- 问题1:根据实验楼写的代码编译为汇编语言时看不懂汇编代码意思。
- 问题1解决方案:网上查找,并询问结对伙伴总结了各行意思。
add:
pushl %ebp ;将%ebp入栈,为帧指针
movl %esp, %ebp ;建立空帧栈
movl 8(%ebp), %eax ;空出地址存变量
addl $3, %eax ;ax中值加3
popl %ebp ;%ebp出栈
ret
call:
pushl %ebp ;将%ebp入栈,为帧指针
movl %esp, %ebp ;为call建立空帧栈
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call add ;调用add函数
leave ;为返回准备栈,相当于%ebp出栈
ret
main:
pushl %ebp ;将%ebp入栈,为帧指针
movl %esp, %ebp ;为main建立空帧栈
subl $4, %esp
movl $8, (%esp) ;
call call ;调用call函数
addl $1, %eax ;值加1
leave
ret
代码托管
(statistics.sh脚本的运行结果截图)
上周考试错题总结
针对以上代码:gcc -c *.c 可以得到m.o,swap.o两个模块,哪些符号会出现在swap.o模块的.symtab条目中()
A .
buf
B .
temp
C .
swap
D .
buffp0
正确答案: A C D
- dll,so文件的链接是运行在()
A .
编译时
B .
加载时
C .
运行时
D .
链接时
正确答案: C
结对及互评
本周结对学习情况
- [20155230](http://www.cnblogs.com/J1n233/p/7708372.html)
- 结对照片
- 结对学习内容
- 理解汇编代码意思,一起补习了汇编知识。
其他(感悟、思考等,可选)
- 本学期每周书上内容信息很多、很杂。经常看完以后不知所云。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 20/20 | 1/1 | 20/20小时 | |
第二周 | 50/70 | 1/2 | 5/25小时 | |
第三周 | 100/170 | 1/3 | 10/35小时 | |
第四周 | 68/238 | 1/4 | 20/55小时 | |
第五周 | 40/278 | 1/5 | 10/65小时 |
-
计划学习时间:20小时
-
实际学习时间:10小时
-
改进情况:
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)