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


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

    教材学习内容总结

    3.2

    1、产生汇编代码(机器级代码):gcc -s xxx.c -o code.s ,另外,反汇编代码中以“.”开头的是指导汇编器和链接器的命令,省略不看。

    2、汇编一个代码:gcc -c code.c -o code.o,产生的code.o是一个二进制格式文件,用od code.o命令查看。

    3、反汇编:objdump -d code.o(对象也可以是可执行文件code),产生的反汇编代码省略了大小指示符。

    4、intel代码省略了指示大小的后缀、寄存器名字前面的%,用不同的方式描述存储器中的位置(如[ebp+4]),包含多个操作数时顺序相反。

    3.3

    1、1字(b)8位,1字(w)16位,双字(l)32位;IA32不支持64位整数运算。

    3.4

    1、三类操作数:立即数、寄存器、存储器位置。$Imm是立即数,Imm是存储器,Ea是寄存器,(Ea)是存储器。

    2、“mov”指令和“=”用法相同,movs符号扩展,movz零扩展。传送指令两个操作数不能都指向存储器位置。

    %dh=CD %eax=98765432
    movb %dh %al %eax=987654CD
    movsbl %dh %eax %eax=FFFFFFFFCD
    movzbl %dh %eax %eax=00000000CD
    传哪个改哪个,寄存器其余三字节不变。

    3、压栈pushl, 弹出popl;栈遵循后进先出原则,栈顶地址最低。

    3.5

    指令很多,很好理解,感觉这几个比较重要: 1、加载有效地址:leal S,D:把S的地址给D。D必须是寄存器。

    2、减法:SUB S,D:D=D-S。

    3、操作数类型:

    一元操作的操作数可以是:寄存器+存储器位置。
    二元操作的源操作数可以是:立即数+寄存器+存储器位置;目的操作数可以是:寄存器+存储器位置。(两种操作数不能都是存储器位置)

    4、移位操作:移位量为单字节,可以是立即数或单字节寄存器元素%cl(只能是这个寄存器)。

    3.6

    1、条件码:单个位。

    2、cmp(根据操作数的差设置条件码)、test指令只改条件码不改寄存器。

    3、set指令操作数大小为单字节,得32位结果要对高24位清零。

    4、跳转指令编码方法:目标指令地址-跳转指令后面那条指令得地址=编码。

    5、goto代码:就是把汇编代码按顺序用c语言写出来,碰到跳转指令用goto。

    6、c语言中的所以循环结构先转化为do-whlie结构,再转化为汇编代码。

    3.7

    1、call:返回地址压栈,跳转到被调用过程起始处。

    2、ret:弹出返回地址,并跳转到这个位置。

    3:%ebp帧指针、%esp栈指针。

    4、p调用q,q的参数放在p的栈帧中,q的栈帧要保存其他寄存器的值等。

    5、寄存器eax、edx、ecx为调用者保存寄存器,ebx、esi、edi为被调用者保存寄存器。

    6、最后附上函数调用时栈帧得结构变化图:

    gdb调试

    P175的表格很重要,有些之前用到过。

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

    1、P128,不明白第一条跳转指令的编码为啥是OxD,没有看懂,3.15习题不会做。

      看了别人的博客,搞明白了,目标指令地址-跳转指令后面那条指令得地址=编码,用的就是这个公式。跳转命令后面的就是目标地址,指令前后两个字节就是编码。

    2、P155习题3.33第三问中x、y的存放地址-4(%ebp)、-8(%ebp),这两个地址是固定的么?就是说系统默认它们永远都是存放在保存的%ebp下面么,可不可以在其他栈帧中未使用的字节空间去存它们?书上只是说它们都是相对于帧指针存的但并没有说存哪。

    代码调试中的问题和解决过程

    P153~P155代码一开始看不明白,结合前面的栈帧结构图反复看,并结合P175的表格,用gdb输出各个寄存器的内容后,明白了函数调用栈帧的过程:

    caller:
    pushl %ebp   //保存%ebp
    movl %esp,%ebp    //设置新的帧指针为旧的栈指针
    subl $24,%esp  //分配24字节的栈空间
    movl $534,-4(%ebp) 
    movl $1057,-8(%ebp) 
    leal -8(%ebp),%eax //计算arg2的地址放入寄存器中,也就是&arg2。(leal操作数必须为寄存器!)
    movl %eax,4(%esp) //将&arg2存入栈
    leal -4(%ebp),%eax 
    movl %eax,(%esp) //同
    call swap_add //调用函数,返回地址压栈。
    一共有24字节的空间,存数据用了4+4=8字节,地址同样8字节,还有8字节未使用。
    
    swap_add:
    ...
    //传参过程:swap_add的参数全部存在caller的栈帧里。
    movl 8(%ebp),%edx//原来是0,保存的%ebp,+4;返回地址,+4;所以为+8.
    movl 12(%ebp),%ecx//8+4=12
    movl (%edx),%ebx
    movl (%ecx),%eax
    movl %eax,(%edx)
    .....
    addl %ebx,%eax//返回值在%eax中。
    ...

    这段代码我还是有问题:在传参时已经传的是地址了,为什么第一行代码movl 8(%ebp),%edx的作用是get xp而不是get *xp?也就是说: 8(%ebp)里的东西为什么不能直接是%ebx里的东西?

    课后作业中的问题和解决过程

    1、P113练习3.1刚开始看题就晕了,很多操作数搞混了,仔细看了表格后,明白了:$Imm是立即数,Imm是存储器位置,Ea是寄存器,(Ea)是存储器位置;此外,比例因子只和变址寄存器的值相乘,最后总结答案如下:

    Ox100
    OxAB
    Ox108
    OxFF
    OxAB(和第二个等价)
    Ox11
    Ox13
    OxFF
    Ox11

    2、P155练习3.32题不会做,反复阅读P153~P154后,发现漏看了返回值放在%eax寄存器中这句话,很关键,解答思路如下:

    1、代码最后两行:
    subl %eax,%edx
    movl %edx,%eax
    以及return x-c,可确定:%edx为x,%eax为c,注意到有后缀“l”,所以c和x为long int型。
    2、看前两行,movsbl、movl命令说明%edx、%eax为双字,第三行代码明显是*p=d,所以,%edx为d,%eax为p,全部为long int型。
    3、完整c代码如下:
    long int fun(long int d,long int p)
    {
        *p=d;
        long int c=p;
        long int x=d;
        return x-c
        }
        //不知道对不感觉上差不多是它。

    本周代码托管

    本周新建了项目,以后代码不用传到java项目里了:

    https://git.oschina.net/20145331/wsc20145331_linux.git

    其他(感悟、思考等,可选)

    看goto代码时感觉把c的循环和分支结构掌握的更好了;把上学期的汇编重学了一遍,感觉这本教材水平很高,一看就会,上学期的汇编课本啥都看不懂;知识很多,写个博客感觉复习了一遍,把调用栈帧的概念和ISA指令体系结构中的细节把握得更准确了,感觉写博客还是有用的。

    学习进度条

     代码行数(新增/累积)博客量(新增/累积)学习时间(新增/累积)重要成长
    目标 5000行 30篇 400小时  
    第一周 140/310 1/5 50/100 基本看得懂汇编代码
  • 相关阅读:
    React Native组件之Text
    React Native的组件ListView
    React Native中的网络请求fetch和简单封装
    解决FileUpload上传大文件报错
    以EF形式操作mysql数据库
    以ADO形式操作mysql数据库
    Docker
    Docker创建镜像文件并在容器中运行
    WIN10下的Docker安装
    MySQL安装
  • 原文地址:https://www.cnblogs.com/bosswsc/p/5967264.html
Copyright © 2020-2023  润新知