• 20145236《信息安全系统设计基础》第6周学习总结


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

    教材内容学习

    一、Y86指令集体系结构

    定义一个指令集体系结构,包括定义各种状态元素、指令集和它们的编码、一组编程规范和异常事件处理。

    二、程序员可见状态

    Y86处理器状态类似于I32。可以访问和修改程序寄存器、条件码、程序计数器和存储器,状态码指明程序是否运行正常。

    RF:程序寄存器 %eax,%ecx,%edx,%ebx,%esi,%edi,%esp(出栈、入栈、调用和返回指令作为栈指针),%ebp

    CC:条件码 ZF、SF、OF(都是一位条件码,用来保存最近的算术或逻辑指令所造成影响的有关信息。)

    PC:程序计数器 存放当前正在执行的指令

    DMEM:存储器 很大的字节数组,保存着程序和数据。Y86程序用虚拟地址来引用存储器位置。

    Stat:程序状态码 它表明程序执行的总体状态。它会指示是正常运行还是出现了某种异常。

    三、Y86指令

    IA32指令集的一个子集,只包括四字节整数操作。寻址方式比较少,操作也比较少。

    IA32的movl指令分成了4个不同的指令:irmovl、rrmovl、mrmovl和rmmovl。分别显示地指明源和目的的格式。

    源操作数: 立即数i、寄存器r、存储器m

    目的操作数: 寄存器r、存储器m

    两个存储器传送指令中的存储器引用方式是简单的基址和偏移量形式。

    在地址计算中,不支持第二变址寄存器和任何寄存器值的伸缩。

    不允许从一个存储器地址直接传送到另一个存储器地址。也不允许将立即数传送到存储器。

    4个整数操作指令

    addl、subl、andl、xorl

    7个跳转指令(jXX)

    jmp、jle、jl、je、jne、jge、jg

    有6个条件传送指令(cmovXX)

    cmovle、cmovl、cmove、cmovne、cmovge、cmovg

    只有当条件码满足所需要的约束时,才会更新目的寄存器的值。

    call指令将返回地址入栈,然后跳到目的地址。ret指令从这样的过程调用中返回。

    pushl和popl指令实现了入栈和出栈。

    halt指令停止指令的执行。对于Y86来说,执行halt指令会导致处理器停止,并将状态码设置为HLT。

    四、指令编码

    每条指令的第一个字节表明指令的类型。这个字节分为两个部分,每部分4位:高4位是代码部分,低4位是功能部分。功能值只有在一组相关指令共用一个代码时才有用。

    整数操作里代码部分均为6,功能部分区分addl,subl,andl,xorl

    分支指令里代码部分均为7

    传送指令里代码部分均为2

    8个程序寄存器中每个都有相应的0~7的寄存器标识符。

    程序寄存器存在一个寄存器文件中,这个寄存器文件就是一个小的、以寄存器ID作为地址的随机访问存储器。当需要指明不应访问任何寄存器时,用ID值0xF表示。

    没有寄存器操作数(分支指令和call指令),就没有寄存器指示符字节。

    只需要一个寄存器操作数的指令(irmovl、pushl、popl),将另一个寄存器指示符设为0xF。

    一个附加的4字节常数字,可作为:irmovl的立即数数据,rmmovl和mrmovl的地址指示符偏移量,分支指令和调用指令的目的地址。

    注意:

    分支指令和调用指令的目的地址是一个相对地址,而不是相对寻址方式。

    所有整数采用小端法编码。当指令按反汇编格式书写时这些字节就以相反的顺序出现。

    五、stat代码可能取值反应了机器的不同状态——

    1. AOK:正常操作(除此之外的任何状态都会使得处理器停止执行指令)
    2. HLT:处理器执行halt指令
    3. ADR:遇到非法地址2015/10/14 17:16:25
    4. INS:遇到非法指令

    六、逻辑设计和硬件控制语言HCL

    要实现一个数字系统需要三个主要的组成部分:

    计算对位进行操作的函数的组合逻辑

    存储位的存储器元素

    控制存储器元素更新的时钟信号

    七、逻辑门

    AND &&

    OR ||

    NOT !

    逻辑门只对单个位的数进行操作,而不是整个字。

    八、组合电路和HCL布尔表达式

    储器来存储程序数据。

    处理器还包括另外一个只读存储器,用来读指令。

    在大多数实际系统中,这两个存储器被合并为一个具有双端口的存储器:一个用来读指令,一个用来读或写数据。

    九、Y86的顺序实现

    SEQ 顺序处理器

    每个时钟周期上,SEQ执行一条完整指令所需的所有步骤

    六个基本阶段

    • 取指 - 译码 - 执行 - 访存 - 写回 - 更新PC

    十、SEQ

    SEQ抽象视图

    程序计数器放在寄存器中

    信息沿线流动

    各个阶段相关的硬件单元负责执行这些处理

    反馈线路包括要写到存储器文件的更新值,以及更新的程序计数器值

    在SEQ中,所有硬件单元的处理都在一个时钟周期内完成

    画图惯例

    浅灰色方块表示硬件单元

    控制逻辑块是用灰色圆角矩形表示的

    线路的名字在白色椭圆中说明

    宽度为字长的数据连接用中等粗度的线表示

    宽度为字节或更窄的数据连接用细线表示

    单个位的连接用虚线

    十一、SEQ的时序

    SEQ的实现包括组合逻辑和两种存储器设备

    时钟寄存器 程序计数器和条件码寄存器

    随机访问存储器 寄存器文件、指令存储器和数据存储器

    组合逻辑不需要任何时序或控制

    由于指令存储器只用来读指令,我们可以将这个单元看成是组合逻辑

    剩下四个(程序计数器、条件码寄存器、数据存储器和寄存器文件)需要对他们的时序进行明确的控制。
    条件码寄存器 只在执行整数运算指令时装载
    数据存储器 只在执行rmmovl、pushl或call时写入
    寄存器文件 两个写端口允许每个时钟周期更新两个程序寄存器。(特殊寄存器ID 0xF表明此端口不应执行写操作)

    1. 组织计算原则

    处理器从来不需要为了完成一条指令的执行而去读由该指令更新了的状态。

    用时钟来控制状态元素的更新,值通过组合逻辑传播。

    2. 取指阶段

    以PC为第一个字节的地址,一次读6个字节。

    icode 控制逻辑块计算指令

    ifun 功能码

    3. 三个一位的信号(根据icode值计算)

    instr_valid 发现不合法的指令

    need_regids 包含寄存器指示符字节吗

    need_valC 包括常数字吗

    后五个字节是寄存器指示符字节和常数字的组合编码。

    4. 译码和写回阶段

    都需要访问寄存器文件,根据四个端口的情况,判断应该读哪个寄存器产生信号valA、valB。

    寄存器文件,支持同时进行两个读和两个写,每个端口有一个地址连接(寄存器ID)和一个数据连接(32根线路),既可以作为寄存器文件的输出字,又可以作为他的输入字。

    5. 执行阶段

    包括算数/逻辑单元(ALU),输出为valE信号。

    ALU通常作为加法器使用

    包括条件码寄存器

    每次运行产生:

    符号、溢出、产生信号set_cc

    6. 访存阶段

    读或者写程序数据。

    两个数据块产生存储器地址和存储器输入证据的值,两个产生控制信号表明应该是读还是写。当执行读操作时,数据存储器产生valM。

    根据icode,imem_error,instr_valid,dmem_error,从指令执行的结果计算状态码Stat。

    7. 更新PC阶段

    产生程序计数器的新值,依据指令的类型和是否要选择分支,新的PC可能是valC、valM或者valP。

    课后习题解答

    4.1

    确定下面的Y86指令序列的字节编码。.pos 0x100表明这段代码的起始地址应该是0x100

    irmovl $15,%ebx
    rrmovl %ebx,%ecx
    loop:
    rmmovl %ecx,-3(%ebx)
    addl %ebx,%ecx
    jmp loop

    答:

    irmovl $15,%ebx ##30f30f000000
    rrmovl %ebx,%ecx ##2031
    loop:
    rmmovl %ecx,-3(%ebx) ##4013fdffff
    addl %ebx,%ecx ##6031
    jmp loop

    4.2

    确定下列每一个字节序列所编码的Y86指令序列。如果有不合法字节,指出其位置。

    A.

    0x100:30f3fcffffff ##irmovl $-4,%ebx
    0x106:406300080000 ##rmmovl %esi,0x800(%ebx)
    0x10c:00 ##halt

    B.

    0x200:a06f ##pushl %esi
    0x202:8008020000 ##call proc
    0x207:00 ##halt
    0x208:
    0x208:30f30a000000 ##irmovl $10,%ebx
    0x20e:90 ##ret
    【此题应该是在熟练掌握各项指令(尤其是特殊指令)的编码基础上进行尝试分解编码序列。例如:在以“a0”开头的编码处,就应该意识到这是一个之后2字节的pushl指令;然后下一个以“80”开头的即call指令(只有五字节),这样就可以得出剩余的00一定是halt。】

    C.

    0x300:505407000000 ##mrmovl 0x7(%esp),%ebp
    0x306:10 ##nop
    0x307:f0 ##非法
    0x308:b01f ##popl %ecx

    4.5

    修改P238图4-6中的Y86代码,使其能计算一个数组的绝对值的和。内循环中使用条件传送。

    源代码:

    int Sum(int Start,int Count)
    {
    int sum = 0;
    while(Count)
    {
    sum+=
    Start;
    Start++;
    Count--;
    }
    return sum;
    }
    【对于内循环的Y86代码,如要计算绝对值之和,只需要在相对于“sum+=*Start”的部分做下改动,加上条件分支(负数取反,正数不变)。如果要用条件传送,则适合cmovg或者cmovge】

    loop:
    mrmovl (%ecx),%esi
    irmovl $0,%edi
    subl %esi,%edi
    cmovg %edi,%esi ##以上代码处理了x<0的情况,下面即和原代码相同
    addl %esi,%eax
    irmovl $4,%ebx
    addl %ebx,%ecx
    irmovl $-1,%ebx
    addl %ebx,%edx
    jne loop

    4.8

    写出信号xor的HCL表达式。输入为a和b

    bool xor = (a && !b) || (!a && b)

    与bool eq = (!a && !b) || (a && b)的区别为,二者互补

    4.10

    写一个电路的HCL代码,对于输入字A,B,C,选择中间值。

    int Med3 = [
    A<=B && A>=C :A;
    A<=C && A>=B :A;
    B<=A && B>=C :B;
    B<=C && B>=A :B;
    1:C;
    ];

    4.16

    根据图4-17中目标代码第9行call处理情况填写具体的处理阶段。

    • 取指

    icode:ifun<-M1[0x023]=8:0

    valC<-M4[0x024] = 0x29

    valP<-0x028

    • 译码

    valB<-R[%esp]=128

    • 执行

    valE<-128-4=124

    • 写回

    R[%esp]<-124

    • 更新PC

    PC<-0x029

    效果是将%esp设置为124,将0x028(返回地址)存放到该存储器地址

    4.17

    写出SEQ中实现need_valC的HCL代码

    bool need_valC = icode in {IIROMVL,IRMMOVL,IMRMOVL,IJXX,ICALL};

    4.19

    寄存器IDdestM表明写端口M的目的寄存器,从存储器中读出来的值valM将放在那里。写出destM的HCL代码。

    int dstM = [
    icode in {IMRMOVL,IPOPL} :rA;
    1:RNONE;
    ]

    实验楼实验

    一、要求:下载Y86模拟器,验证教材上不少于三组HCL代码;构建YIS环境(操作性的代码见下);YIS手册下载;YIS测试

    cd ~/Code/shiyanlou_cs413

    wget http://labfile.oss.aliyuncs.com/courses/413/sim.tar

    tar -xvf sim.tar

    cd sim

    sudo apt-get install tk

    sudo ln -s /usr/lib/x86_64-linux-gnu/libtk8.6.so /usr/lib/libtk.so

    sudo ln -s /usr/lib/x86_64-linux-gnu/libtk8.6.so /usr/lib/libtk.so

    make

    二、构建YIS环境的过程如下(实验楼环境下)

    三、汇编所有代码结果

    进入测试代码 cd y86-code

    进行汇编 make asuml.yo

    汇编所有代码结果 make all

    四、测试书中P239代码asuml.ys,得到的代码如下:

    | /* $begin code-yso */
      | /* $begin code-ysa */
      | # Execution begins at address 0
      | # This version uses a leave instruction
      0x000:  |     .pos 0
      0x000: 30f400040000 | init:   irmovl Stack, %esp      # Set up Stack pointer
      0x006: 30f500040000 |     irmovl Stack, %ebp      # Set up base pointer
      0x00c: 7024000000   |     jmp Main        # Execute main program
      | 
      | # Array of 4 elements
      0x014:  |     .align 4
      0x014: 0d000000 | array:  .long 0xd
      0x018: c0000000 |     .long 0xc0
      0x01c: 000b0000 |     .long 0xb00
      0x020: 00a00000 |     .long 0xa000
      | 
      0x024: 30f004000000 | Main:   irmovl $4,%eax
      0x02a: a00f |     pushl %eax  # Push 4
      0x02c: 30f214000000 |     irmovl array,%edx
      0x032: a02f |     pushl %edx  # Push array
      0x034: 803a000000   |     call rSum   # Sum(array, 4)
      0x039: 00   |     halt
      | 
      |     # int Sum(int *Start, int Count)
      0x03a: a05f | rSum:   pushl %ebp
      0x03c: 2045 |     rrmovl %esp,%ebp
      0x03e: 30f014000000 |     irmovl $20,%eax
      0x044: 6104 |     subl %eax,%esp
      0x046: a03f |     pushl %ebx
      0x048: 503508000000 |     mrmovl 8(%ebp),%ebx
      0x04e: 50050c000000 |     mrmovl 12(%ebp),%eax
      0x054: 6200 |     andl %eax,%eax
      0x056: 718b000000   |     jle L38
      0x05b: 30f2f8ffffff |     irmovl $-8,%edx
      0x061: 6024 |     addl %edx,%esp
      0x063: 30f2ffffffff |     irmovl $-1,%edx
      0x069: 6020 |     addl %edx,%eax
      0x06b: a00f |     pushl %eax
      0x06d: 30f204000000 |     irmovl $4,%edx
      0x073: 2030 |     rrmovl %ebx,%eax
      0x075: 6020 |     addl %edx,%eax
      0x077: a00f |     pushl %eax
      0x079: 803a000000   |     call rSum
      0x07e: 502300000000 |     mrmovl (%ebx),%edx
      0x084: 6020 |     addl %edx,%eax
      0x086: 708d000000   |     jmp L39
      0x08b: 6300 | L38:    xorl %eax,%eax
      0x08d: 5035e8ffffff | L39:    mrmovl -24(%ebp),%ebx
      0x093: d0   |     leave
      0x094: 90   |     ret
      | 
      0x400:  |     .pos 0x400
      0x400:  | Stack:  # The stack goes here
      | /* $end code-ysa */
      | /* $end code-yso */
    

    代码托管

    代码托管链接

  • 相关阅读:
    写在最顶部
    新一轮的战斗。
    Codeforces Round #180
    git学习笔记
    感悟、方向、计划
    .NET (c#)序列化和反序列化
    类的序列化发送和接受
    Log4Net: TextBoxBaseAppender
    任何成功不能只靠自己一个人
    技术问题,总是在短期被高估,在长期被低估
  • 原文地址:https://www.cnblogs.com/feng886779/p/5989116.html
Copyright © 2020-2023  润新知