2019-2020-1 20175319 《信息安全系统设计基础》第三周学习总结

2018-2019-1 20175319 《信息安全系统设计基础》第三周学习总结

教材学习内容总结

汇编语言

  • 汇编语言
    • 汇编语言是直接面向处理器的程序设计语言
    • 是机器指令的一种符号表示
    • 由一条条指令构成
    • 近距离观察机器代码
  • 代码编译过程

  • 入门级概念
    • 两个抽象
      • 指令集体系结构或指令集架构来定义机器级程序的格式和行为,它定义了处理器状态、指令的格式,以及每条指令对状态的影响。
      • 机器级程序使用的内存地址,提供的内存模型看上去是一个非常大的字节数组
    • X86-64指令
      • 指令长度:1到15个字节不等
      • 指令格式:OPER [DEST [,SRC]] ;注释
  • 生成汇编文件
    使用GCC编译器
    gcc -Og -S code.c
  • 反汇编
    使用OBJDUMP
    gcc -c code.c
    objdump -d code.o

处理器

数据格式

访问信息

  • X86-64中,中央处理单元(CPU)包含一组16个存储64位值的通用目的寄存器,用来存储整数数据和指针。
  • 操作数指示符
  1. 立即数
  2. 寄存器
  3. 内存引用
  • 数据传送指令
    mov类指令:将源操作数的值复制到目的操作数中。
  • 寻址方式
    • 立即数寻址
      操作数在指令中直接给出
      注意:只能用于源操作数,数据长度应和目标操作数长度匹配
    • 寄存器寻址
      数存放在CPU的内部寄存器中
      注意:源操作数和目的操作数的长度应该一致
    • 存储器寻址
      操作数存放在存储器中,指令中给出操作数的偏移地址信息

算术和逻辑操作

  • 加载有效地址指令leal实际上就是movl指令的变形。它的指令形式是从存储器读取数据到寄存器,但实际根本没引用存储器。
  • 一元操作:只有一个操作数,既是源又是目的,可以是一个寄存器,或者存储器位置。
    • INC 加1
    • DEC 减1
    • NEG 取负
    • NOT 取补
  • 二元操作:第一个操作数可以是立即数、寄存器或者储存器位置;第二个操作数既是源也是目的。可以是寄存器或者储存器位置,但是不能同时是储存器位置。
    • ADD 加
    • SUB 减
    • IMUL 乘
    • XOR 异或
    • OR 或
    • AND 与
  • 移位操作:先给出移位量,第二项给出要移位的数值。
    • SAL 左移
    • SHL 左移(等同于SAL)
    • SAR 算术右移
    • SHR 逻辑右移


  • 特殊算术操作
    • 乘法
      • 乘积截断
        • imull双操作数
        • 从两个32位操作数产生一个32位的乘积。
      • 乘积不截断
        • mull无符号数乘法
        • imull有符号数乘法
      • 要求一个参数必须在寄存器%eax中,另一个作为指令的源操作数给出。
      • 乘积的高32位在%edx中,低32位在%eax中。
    • 除法
      • 有符号除法
      • idivl 操作数
        • 将DX:AX中的64位数作为被除数,操作数中为除数
        • 结果:商在AX中,余数在DX中。
      • 无符号除法
      • divl指令
        • 通常会事先设定寄存器%edx为0.

控制类指令

  • 条件码
    • CF: 进位标志。最近的操作使用最高位产生了进位。可以用来检查无符号操作数的溢出。
         - ZF: 零标志。最近的操作得出的结果为0.
         - SF: 符号标志。最近的操作得到的结果为负数。
         - OF: 溢出标志。最近的操作导致一个补码溢出——正溢出或负溢出。
    • 常用的访问方法有三种:
      (1)可以根据条件码的某个组合,将一个字节设置为0或者1
      (2)可以条件跳转到程序的某个其他的部分
      (3)可以有条件地传送数据
  • SET指令:执行比较指令,根据计算t=a-b的结果设置条件码
  • 跳转指令
    • 无条件跳转
    • 直接跳转:跳转目标是作为指令的一部分编码的
    • 间接跳转:跳转目标是从寄存器或存储器位置中读出的
  • 比较和测试指令

  • 访问条件码指令

  • 跳转指令

  • 循环指令
  1. do-while 循环
    do body-statement while(test-expr);
  2. while 循环
    while(test-expr) body-statement
  3. for 循环
    for(init-expr; test-expr; update-expr) body-statement

过程

  • 过程:一组指定的参数和一个可选的返回值实现某种功能。
  • 形式:函数、方法、子例程、处理函数等。
  • 实现过程需要的机器级支持机制
    • 传递控制:将控制从函数P转移到函数Q
    • 传递数据:把数据作为参数传递,从过程不返回或返回一个或多个值
      • X86-64中,可以通过寄存器最多传递6个整型参数
    • 分配和释放内存
      • 栈上的局部存储
      • 寄存器中的局部存储空间
  • 栈帧
    • 栈帧也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构。
    • 寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低地址)。
  • 函数栈帧


支持过程调用和返回的指令:

数组及数据结构

  • 数组
    • 嵌套的数组:
      int A[5][3]
    • 定长数组:
      #define N 16 typedef int fix_matrix[N][N]
    • 变长数组
      int A[expr1][expr2]
  • 结构体
    用关键字struct声明,将多个对象集合到一个单位中
  • 联合体
    用关键字union声明,允许用几种不同的类型来引用一个对象
  • 数组分配和访问
    Xa代表的是起始地址,汇编代码使用move指令来简化访问:
    movl (%edx,%ecx,4),%eax

异质的数据结构

  • 结构
    • 所有的组成部分在存储器中连续存放,指向结构的指针指向结构的第一个字节。
    • 结构的各个字段的选取是在编译时处理,机器代码不包含字段的声明或字段名字的信息。
  • 联合
    • 一个联合的总大小等于它最大字段的大小
    • 指向一个联合的指针,引用的是数据结构的起始位置。
  • 结构和联合的应用
    • 如果两个数据互斥,减少空间
    • 访问不同数据的位模式
    • 使用不同的位模式访问数据
    • 用有符号数据存储,而返回的确实无符号的数据。
  • C语言提供了两种结合不同类型的对象来创建数据类型的机制:
    • 结构(structure),用关键字struct声明, 将多个对象集合到一个单位中。
    • 联合(union), 用关键字union声明,允许用集中不同的类型来引用一个对象。
  • 数据对齐

在计算机程序中将控制与数据结合

  • 指针
    • 指针用&符号创造、用*符号间接引用
    • 指针从一个类型转为另外一个类型,只是伸缩因子变化,不改变它的值
    • 指针可以指向函数
  • GDB调试器
    GDB支持对机器级程序的运行时评估和分析。
    常用命令:
  • 内存越界引用与缓冲区溢出

浮点代码

  • XMM寄存器用来向函数传递浮点参数,以及从函数返回浮点值
    • XMM寄存器%xmm0~%xmm7最多可以传递8个浮点参数。
    • 函数使用寄存器%xmm0来返回浮点值
    • 所有的XMM寄存器都是调用者保存的。被调用者可以不用保存就覆盖这些寄存器中任意一个
  • GCC只用标量传送操作从内存传送数据到XMM寄存器或从XMM寄存器传送数据到内存。

代码学习内容


考试错题总结

  • 1.下面的跳转指令与ZF有关的是()
    A.jmp B.je C.js
    D.ja E.jb F.jbe
    正确答案: B D F
    解析:

  • 2.x86-64 Linux中,有关MOV,下面正确的是()
    A .movw $0x50, %eax
    B .movw %bp, %sp
    C .movl ($1234), ($2345)
    D .movb $10, (%rsp)
    E .movq %rax, 4(%rbp)
    F .movb (%rdi, %rcx), %ah
    正确答案: B D E F

码云链接

https://gitee.com/J20175319/xinan_foundation/tree/master/week3

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 101/101 1/1 20/20
第二周 49/150 1/2 18/38
第三周 22/172 1/3 11/49

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

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

  • 计划学习时间:XX小时

  • 实际学习时间:XX小时

  • 改进情况:

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

参考资料

原文地址:https://www.cnblogs.com/killer-queen/p/11656021.html