20175221 《信息安全系统设计基础》第5周学习总结

教材学习内容总结

  • 实验楼部分

  • X86 寻址方式经历三代:
  • 1 DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
    2 8086的分段模式
    3 IA32的带保护模式的平坦模式
  • 二进制文件可以用od 命令查看,也可以用gdb的x命令查看。有些输出内容过多,我们可以使用 more或less命令结合管道查看,也可以使用输出重定向来查看
  • od code.o | more
    od code.o > code.txt
  • gcc -S xxx.c -o xxx.s  获得汇编代码,也可以用 objdump -d xxx 反汇编; 函数前两条和后两条汇编代码,所有函数都有,建立函数调用栈帧
  • 64位机器上想要得到32代码:gcc -m32 -S xxx.c
    MAC OS中没有objdump, 有个基本等价的命令otool
    Ubuntu中 gcc -S code.c (不带-O1) 产生的代码更接近教材中代码(删除"."开头的语句)
  • PPT部分

  • x86-64的CPU包含一组16个存储64位的通用目的寄存器,如图:
  • MOV中的一些常见的数据传送指令
  • 函数调用时栈帧相对应的变化
  • 操作部分

  • 对教材P114的C语言文件 mstore.c 使用命令 gcc -Og -S mstore.c 可产生其对应的汇编文件 mstore.s 但是不做进一步操作;使用命令 gcc -Og -c mstore.c 可产生其目标代码文件 mstore.o ,但由于其是二进制格式,所以无法直接查看
  • 使用命令 objdump -d mstore.o 可反汇编查看机器代码的内容
  • 左边是14个十六进制字节值,被分成若组,每组都是一条指令,右边是等价的汇编语言
  • 我们再查看 mstore.s 的内容(突然忘记怎么打印文本内容,百度后参考了Linux常用基本命令(cat),重新学习了下)
  • 所有以 ‘.’ 开头的行都是指导汇编器和链接器工作的伪指令,我们通常可以忽略这些行
  • 将实验楼的代码简单修改如下
  • #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int step1(int x)
    {
      return x + 3;
    }
    
    int step2(int x)
    {
      return step1(x);
    }
    
    int main(void)
    {
      printf("%d",step2(8) + 1);
      return 0;
    }
  • 参考学习了GDB调试命令---反汇编相关,列出部分我觉得较为实用的调试命令:
  • 反汇编命令:disas/disass/disassemble,例如:disas main,显示main函数对应的汇编代码
    查看相关信息:info,例如:info line/registers/break,查看某个line的相关信息/各寄存器的值/所有断点
    开始执行:r
    设置断点:b, 格式:b *内存地址
    单步步过:ni
    单步步入:si
    显示某寄存器的值:display  例如:display /x $eax
    查看变量值:p  格式: p 变量名
  • 下边将对修改过的代码进行简单的GDB反汇编调试,并加入我个人的理解(有误请指)

  • 进入GDB调试,首先在main处设置一个断点,运行到main时, disas main 查看main的汇编代码, info registers 查看各寄存器的值
  • 注意到此时堆栈指针值为 0xffffd0ec ,基址指针的值 0xffffd0f8
  • 在分析之前先进行设置: display /i $pc ,这条命令可显示我们在单步调试时所执行的语句,记录每一步的$esp和$ebp。如下 call 指令将要调用子函数step2
  • 查看函数step2的汇编语句
  • si 继续下一步,运行到函数step2处,发现栈顶发生变化,一句句理解:
  • 左边终端:此时执行的语句为  push %ebp ,意味着向栈里压入了一个东西,栈顶地址由 0xffffd0e8 变为 0xffffd0e4 ,减少了4字节。为什么是减法呢?因为是向低地址增长的
  • 右边终端:此时执行的语句为  mov %esp,%ebp ,表示将栈顶指针的值赋给基址,所以二者的值相同,同为0xffffd0e4
  • 注意到下一句将调用函数 <__x86.get_pc_thunk.ax> ,参考了深入了解GOT,PLT和动态链接,给出了如下解释:作用就是把esp(即返回地址)的值保存在eax(PIC寄存器)中, 在接下来寻址用
  • <__x86.get_pc_thunk.ax> 获取地址,有 mov  ret 等部分,其中esp参与运算,过程中值会变化。mov:将esp的值保存在eax中   ret:将参与运算的esp弹出返回,恢复到与ebp相同的值
  • 重点再来看一下出栈时的地址变化:
  • 执行完 leave 后,ebp恢复为原来的值,这是为什么?ebp不是本应一直保存esp的初始地址吗?
  • 或许是因为,虽然ebp的值起初是存在了栈中,但 leave将存在栈中的值弹了出来,赋给了变量ebp
  • 而在执行完 ret 后,ebp出栈了,此时栈空,所以栈顶会变成初始的值。且与开始进栈时相反,出栈栈顶+4,即 0xffffd0e8+0x4=0xffffd0ec  
  • 这次的GDB调试,受限于所学,只是浅尝辄止,后边会继续努力

教材学习中的问题和解决过程

  • 问题1:

  • PPT中有gcc -Og -o p p1.c p2.c 命令,且说明 -Og 告诉编码器采用的等级,一般认为第二级优化-O2是较好的选择。那么,①-O2是最高等级的优化了吗?②优化等级是越高越好吗?③这里的-Og怎么理解呢 ?
  • 问题1解决方案:

  • 参考了(gcc -O0 -O1 -O2 -O3 四级优化选项及每级分别做什么优化):
  • gcc为了满足用户不同程度的的优化需要,提供了从 O0-O3 以及 -OS这几种不同的优化级别供大家选择,从而对{编译时间,目标文件长度,执行效率}这个三维模型进行不同的取舍和平衡。 -Ox (x=0,1,2,3,亦或是其他字母)根据x值大小包含由低到高的一些优化选项,所以 -O2 并不是最高等级的优化。值得一提的是,即使是最高优化选项 -O3  ,也并没有包含所有的优化选项,其为了大多数人使用方便而预设的宗旨,也注定其并不是优化等级是越高越好。 用教材中的话来说,就是使用较高级别优化产生的代码就会严重变形,以至于产生的机器代码和初始源代码之间的关系非常难以理解。
  • 对于 -Og ,参考了(GCC中-O1 -O2 -O3 优化的原理是什么?)中的高赞回答: 该标识会精心挑选部分与-g选项不冲突的优化选项,当然就能提供合理的优化水平,同时产生较好的可调试信息和对语言标准的遵循程度。
  • 问题2:

  • 移位操作中的“逻辑右移”与“算术右移”的命令如此相似,那二者本质区别在哪呢?
  • 问题2解决方案:

  • 参考(逻辑右移和算术右移有什么区别):逻辑右移就是不考虑符号位,右移一位,左边补零即可;算术右移需要考虑符号位,右移一位,若符号位为1,就在左边补1;否则,就补0。所以算术右移也可以进行有符号位的除法,右移,n位就等于除2的n次方
  • 例如,8位二进制数11001101分别右移一位。
  • 逻辑右移就是[0]1100110,算术右移就是[1]1100110
  • 问题3:

  • PPT中数据对齐一处有字节分配的情景,并没有按照最小字节分配,而是遵循了字节对齐的规则。那么,①字节对齐的意义何在?②是按照什么规则进行字节对齐的呢?
  • 问题3解决方案:

  • 参考了(字节对齐的意义):各个硬件平台对存储空间的处理不尽相同,比如一些CPU访问特定的变量必须从特定的地址进行读取,在这种架构下就必须进行字节对齐,否则读取不到数据或者读取到的数据是错误的。而字节对齐让CPU快速读取到相应的数据的同时,可以提高程序的效率。
  • 字节对齐规则如下:
  • 代码调试中的问题和解决过程

  • 问题1:

  • 在查看机器代码文件的内容时,我们除了按照教材那样使用命令 objdump -d mstore.o 外,还可以如何做
  • 问题1解决方案:

  • 我们可以进入GDB调试模式,输入 (gdb) x/14xb multstore ,意思是显示从函数multstore 所处地址开始的14个十六进制格式表示的字节
  • 我们还可以使用前边学习过的od命令来将显示内容以十六进制显示,并以每个字节为单位: od -tx1 mstore.o
  • 但对比来看,我们若是需要进行汇编分析,那还是 object dump 较为实用些
  • 问题2:

  • 在使用gdb反汇编命令调试程序时,出现了权限不够的提示
  • 问题2解决方案:

  • 参考了gdb调试run之后说权限不够,是因为 gdb-text.o 是没有链接的编译文件,没办法执行。需要重新编译-- 编译命令:gcc -g -o gdb-text gdb-text.c  调试命令:gdb -q gdb-text 。
  • 问题3:

  • 在转32位时报错
  • 问题3解决方案:

  • 参考了gcc -m32报错的解决办法,使用命令 sudo apt-get install libc6-dev-i386 安装操作系统支持包即可

心得体会

通过这次简单的GDB调试,才知道即使在c中短短的一个赋值语句,一个返回语句,在汇编语言中都可能包含着许多出栈,压栈,传参等操作。只是前人做了许多努力,我们现在才轻松了许多。但不代表我们就可以对汇编语言视若无睹,对汇编语言的学习,重点还是要加强对它的理解,多动手实践应用它

上周考试错题总结

学习进度条

  代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时  
第一周 53/53 1/1 20/20  
第二周 200/253 2/3 21/20  
第三周 100/353 1/4 30/50  

尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。 耗时估计的公式 :Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

参考:软件工程软件的估计为什么这么难软件工程 估计方法

  • 计划学习时间:XX小时
  • 实际学习时间:XX小时
  • 改进情况:

(有空多看看现代软件工程 课件 软件工程师能力自我评价表)

参考资料

原文地址:https://www.cnblogs.com/zxja/p/11614028.html

时间: 2024-10-14 05:34:52

20175221 《信息安全系统设计基础》第5周学习总结的相关文章

20145216 史婧瑶《信息安全系统设计基础》第一周学习总结

20145216 <信息安全系统设计基础>第一周学习总结 教材学习内容总结 Linux基础 1.ls命令 ls或ls .显示是当前目录的内容,这里“.”就是参数,表示当前目录,是缺省的可以省略.我们可以用ls -a .显示当前目录中的所有内容,包括隐藏文件和目录.其中“-a” 就是选项,改变了显示的内容.如图所示: 2.man命令 man命令可以查看帮助文档,如 man man : 若在shell中输入 man+数字+命令/函数 即可以查到相关的命令和函数:若不加数字,那man命令默认从数字较

20145311 《信息安全系统设计基础》第一周学习总结

20145311 <信息安全系统设计基础>第一周学习总结 教材学习内容总结 常用的部分命令 CTRL+SHIFT+T:新建标签页,编程时有重要应用: ALT+数字N:终端中切换到第N个标签页,编程时有重要应用: Tab:终端中命令补全,当输入某个命令的开头的一部分后,按下Tab键就可以得到提示或者帮助完成: CTRL+C:中断程序运行 Ctrl+D:键盘输入结束或退出终端 Ctrl+S: 暂定当前程序,暂停后按下任意键恢复运行 Ctrl+A: 将光标移至输入行头,相当于Home键 Ctrl+E

20145216史婧瑶《信息安全系统设计基础》第九周学习总结

20145216史婧瑶<信息安全系统设计基础>第九周学习总结 教材内容总结 第十章 系统级I/O 输入/输出(I/O)是在主存和外部设备之间拷贝数据的过程. 第一节 Unix I/O 这一节涉及到操作系统的基本抽象之一--文件.也就是说,所有的I/O设备都被模型化为文件,而所有的输入输出都被当做对相应文件的读/写.相关的执行动作如下: 1.打开文件: 应用程序向内核发出请求→要求内核打开相应的文件→内核返回文件描述符 文件描述符:一个小的非负整数,用来在后续对此文件的所有操作中标识这个文件.有

20145311 《信息安全系统设计基础》第二周学习总结

20145311 <信息安全系统设计基础>第二周学习总结 教材学习内容总结 重新学习了一下上周的一部分命令:grep main wyx.c(grep的全文检索功能)ls > ls.txt :ls内容输出到文本find pathname -mtime -n/+nfind -size -n/+n (find的功能还是比较强大) 简单地学习了一下vim编辑器,跟着vimtutor简单地学了一些,在linux bash中使用vim能够极大地提高效率, vim的用法比较多,只学习了其中简单的一部分

20145339《信息安全系统设计基础》第一周学习总结

20145339顿珠达杰<信息安全系统设计基础>第一周学习总结 ◆ Linux是一个操作系统.如果使用GUI,Linux和Windows没有什么区别.Linux学习应用的一个特点是通过命令行进行使用. 物理机系统上可以通过使用[Ctrl]+[Alt]+[F1]-[F6]进行终端和图形界面切换,在线实验环境中按下[Ctrl]+[Alt]+[F7]来完成切换.普通意义上的 Shell 就是可以接受用户输入命令的程序,Unix/Linux 操作系统下的 Shell 既是用户交互的界面,也是控制系统的

2017-2018-1 20155228 《信息安全系统设计基础》第九周学习总结

2017-2018-1 20155228 <信息安全系统设计基础>第九周学习总结 教材学习内容总结 常见的存储技术 RAM 随机访问存储器(Random-Access Memory, RAM)分为两类:静态的和动态的.静态 RAM(SRAM)比动态RAM(DRAM)更快,但也贵得多.SRAM用来作为高速缓存存储 器,既可以在CPU芯片上,也可以在片下.DRAM用来作为主存以及图形系统的帧缓冲 区.典型地,一个桌面系统的SRAM不会超过几兆字节,但是DRAM却有几百或几千兆 字节. SRAM将每

2017-2018-1 20155332 《信息安全系统设计基础》第九周学习总结

2017-2018-1 20155332 <信息安全系统设计基础>第九周学习总结 教材学习内容总结 简单模型中,存储器是一个线性的字节数组.真实模型中,是一个具有不同容量,成本,访问时间的存储层次结构(存储器山) 程序的局部性很重要,对程序性能有很重要的影响. 计算机系统一个基本而持久的思想,如果你理解了系统是如何将数据在存储器层级结构中上下移动,你就可以编写程序,让数据存储在层次结构中较高的地方,从而CPU可以更快的访问到他们. 编写程序实现功能是最简单的,如何让编写的程序拥有最高的性能,例

2017-2018-1 20155227 《信息安全系统设计基础》第九周学习总结

2017-2018-1 20155227 <信息安全系统设计基础>第九周学习总结 教材学习内容总结 第六章 随机访问存储器 随机访问存储器分为:静态RAM(SRAM)和动态RAM(DRAM),静态RAM(SRAM)比动态RAM(DRAM)更快,但也贵很多. (1)静态RAM SRAM将每个位存储在一个双稳态的存储器单元里,每个单元是用一个六晶体管电路来实现的. 属性:它可以无限制地保持在两个不同的电压配置或状态之一.其他任何状态都是不稳定的. 特点:由于SRAM的双稳态特性,只要有电,它就会永

2017-2018-1 20155334 《信息安全系统设计基础》第九周学习总结

2017-2018-1 20155334 <信息安全系统设计基础>第九周学习总结 学习目标: 了解常见的存储技术(RAM.ROM.磁盘.固态硬盘等) 理解局部性原理 理解缓存思想 理解局部性原理和缓存思想在存储层次结构中的应用 高速缓存的原理和应用 教材学习内容总结 一.常见的存储技术: 基本的存储技术包括随机存储器(RAM).非易失性存储器(ROM)和磁盘. 1. RAM分静态RAM(SRAM)和动态RAM(DRAM). 2. SRAM快些,主要用做CPU芯片上的高速缓存,也可以用作芯片下的

2017-2018-1 20155331 《信息安全系统设计基础》第九周学习总结

2017-2018-1 20155331 <信息安全系统设计基础>第九周学习总结 教材学习内容总结 存储器层次结构 存储技术 随机访问存储器 随机访问存储器分为:静态的SRAM.动态的DRAM 静态RAM: SRAM的特点:存储器单元具有双稳态特性,只要有电就会永远保持它的值,干扰消除时,电路就会恢复到稳定值. 动态RAM: DRAM的特点:每一位的存储是对一个电容的充电:对干扰非常敏感. 用途:数码照相机和摄像机的传感器 DRAM存储不稳定的应对机制: 存储器系统必须周期性地通过读出,或者重