• 2017-2018 20155309南皓芯 信息安全系统基础设计第五周博客


    教材中的内容及学习

    这次学习的内容是教材第三章的内容,第三章的内容是程序的机器化表示。

    历史观点

    ntel处理器的换代:8086——80286——i386——i486——Pentium——PentiumPro——PentiumII——PentiumIII——Pentium4——Pentium4E——Core2——Corei7。

    这些所有的代都是Intel系列的,Intel系列本身有很多名字,比如x86,比如IA32,Intel系列中64位扩展称为x86-64。最常用的是x86。也就是说x86就是Intel每一代处理器的统称。

    8086和80286的存储器模型都已经过时了,从i386开始提供的平坦寻址模式也是linux使用的模式,这是将存储空间看做一个大的字节数组。

    看来i386是一个转折点,从这里开始系统扩展为32位,同时,GCC为32位执行的默认调用仍然假设是为i386机器产生的代码,Intel系列,x86,是向后兼容的,所以i386的可以执行的代码,后面的都可以执行。

    ntel处理器系列俗称x86,开始时是第一代单芯片、16位微处理器之一。

    每个后继处理器的设计都是后向兼容的——较早版本上编译的代码可以在较新的处理器上运行。
    X86 寻址方式经历三代:

    1. DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
    2. 8086的分段模式
    3. IA32的带保护模式的平坦模式

    程序编码

    这一小节主要是对一些命令进行阐述。
    gcc -O1 -s xxx.c 输出 汇编代码

    gcc -O1 -c xxx.c 输出 目标代码

    objdump -d xxx.o 反汇编机器代码(包括目标代码和可执行代码,两者的区别在于偏移地址)

    gdb 可以直接对机器代码使用(包括目标代码和可执行代码)

    gcc -s产生的汇编代码中,所有以点开头的行都是用于指导汇编器和链接器的。

    gcc和objdump产生的汇编代码是ATT风格,微机原理里面学习的是Intel风格。有所不同,但本质没有改变。

    机器级代码

    1.程序计数器
    2.整数寄存器
    3.条件码寄存器
    4.浮点寄存器

    代码示例

    int accum = 0;
     
    int sum(int x, int y)
    {
         int t = x+y;
         accum+=t;
         return t;
    }
    

    在命令行上使用 “-S”选项

    unix〉gcc -02 -S code.c

    就能看到编译器产生的汇编代码:

    sum:
           pushl %ebp
           movl %esp , %ebp
           movl 12(%ebp) , %eax
           addl 8(%ebp) , %eax
           addl %eax , accum
           movl %ebp , %esp
           popl %ebp
           ret
    

    如果对code.c 使用“-c”选项则会产生一个二进制的文件code.o

    unix〉gcc -02 -c code.c
    

    数据格式

    访问信息

    这是IA32中央处理器所包含的一组八个存储单元的32位存储器。前六个是通用寄存器,对它们的使用没有限制。前三个寄存器(%eax,%ecx,%edx)的保存和恢复惯例不同于接下来的三个寄存器(%ebx,%esi,%edi)。最后两个寄存器保存着指向程序栈重要位置的指针,称为栈指针和帧指针。数据存放在寄存器中进行加减乘除等一些操作。原来的寄存器是16位的所以如图所示蓝色部分是0-15,之后寄存器进行了扩充,变成了32位的即0-31。

    (1) 操作数指示符

    操作数被分成三种类型:立即数、寄存器、存储器引用。还有不同的寻址模式。
    其次还有常见的汇编程序的数据传送指令

    示例代码

    int swap_add(int *xp, int *yp)
    {
        int x = *xp;
        int y = *yp;
        *xp = y;
        *yp = x;
        return x+y;
    }
     
    int caller()
    {
        int arg1 = 534;
        int arg2 = 1057;
        int sum = swap_add(&arg1, &arg2);
        return sum;
    }
    

    汇编代码为:

    swap_add:
    .LFB0:
        .cfi_startproc
        pushl   %ebx
        .cfi_def_cfa_offset 8
        .cfi_offset 3, -8
        movl    8(%esp), %ebx
        movl    12(%esp), %ecx
        movl    (%ebx), %edx
        movl    (%ecx), %eax
        movl    %eax, (%ebx)
        movl    %edx, (%ecx)
        addl    %edx, %eax
        popl    %ebx
        .cfi_def_cfa_offset 4
        .cfi_restore 3
        ret
        .cfi_endproc
    caller:
    .LFB1:
        .cfi_startproc
        subl    $24, %esp
        .cfi_def_cfa_offset 28
        movl    $534, 16(%esp)
        movl    $1057, 20(%esp)
        leal    20(%esp), %eax
        movl    %eax, 4(%esp)
        leal    16(%esp), %eax
        movl    %eax, (%esp)
        call    swap_add
        addl    $24, %esp
        .cfi_def_cfa_offset 4
        ret
        .cfi_endproc
    

    教材中的问题以及解决

    1.首先这次的虚拟机又出现了新的问题,并且尝试解决问题,出现的问题如下图所示。

    在出现这种情况的时候,你不能进行任何操作,而且电脑一直处于运行状态,当你点击最右边的按键进行取消的时候,电脑也会用很长的时间来取消。在发现这种问题之后,我上网搜索了答案。(https://cnzhx.net/blog/wont-upgrade-virtualbox-for-a-long-time/)
    我将电脑的虚拟机恢复到之前的版本然后解决了问题。

    2.栈破坏检测是如何运行的?

    原来碰到本来运行很正常的程序,忽然弹出错误对话框,“

    "0X"指令引用的"0X**"内存。该内存不能为"read"或"written"”。接着程序就崩溃退出。
    这样的错误是程序存在BUG引起堆栈被破坏导致的。不要小看这样的问题,这种导致堆栈破坏的BUG因为不知道下一次什么时候就会出现,
    具有很强的隐蔽性。所以调试起来也很麻烦。

    主要是一些不安全的库函数的使用,特别是对特定大小的数组进行的一些操作,特别要注意.。

    代码调试中的问题以及解决

    1.在转移过程中出现了问题

    后来发现是自己没有注意一些小问题。

    首先是调用函数时pc的位置发生了变化而自己却没有注意。并且在返回值的函数上出现了问题。

    代码托管

    学习与感悟

    本周老师在蓝墨云班课上留了37道题。做这几十道题我用了几个小时的时间,用几个小时的时间来学习教材上的知识。虽然时间很长,但是感觉自己收获的东西也很多。这次第三章的学习有100多页,刚看的时候头脑确实很迷茫,但是在看到前人的总结与经验之后,发现整体的框架还是非常好的。所以现在来看能够理解的东西也变得多了。

    学习时间条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 10 /10 1/1 10/10
    第二周 40 /70 2/4 18/38
    第三周 150/200 3/7 15/60
    第四周 180/250 4/8 13/70

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

    计划学习时间:13小时

    实际学习时间:17小时

    改进情况:多提出问题,多解决问题。

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

    参考资料
    《深入理解计算机系统V3》学习指导
    ...

  • 相关阅读:
    设备arduino的编译目录
    c# await 关键字错误
    开篇 hello 内Cool超人
    在Windows Azure虚拟机上开发Windows 8 应用
    使用LVS实现负载平衡之Windows Server 2008配置
    IDC Digital Transition Annual Festival(2018.10.19)
    Dell Technology Summit(2018.10.17)
    Lean Data Innovation Sharing Salon(2018.09.15)
    Trusted Block Chain Summit(2018.10.09)
    Artificial Intelligence Computing Conference(2018.09.12)
  • 原文地址:https://www.cnblogs.com/nhx19970709/p/7710971.html
Copyright © 2020-2023  润新知