• 第三章 程序的机器级表示


    程序的机器级表示

    3.1历史观点

       8086—〉80286—〉i386—〉i486—〉Pentium—〉PentiumPro—〉Pentium—〉Pentium—〉Pentium4—〉Pentium4e—〉Core 2 Duo —〉Core i7

    3.2程序编码

       1.gcc -01 –o p p1.c p2.c      使用第一级优化

       2.程序计数器(%eip)指示将要执行的下一条指令在存储器中的地址。

       3.寄存器文件

       4.-S:C语言编译器产生的汇编代码

            例:gcc -01 –S code.c 会产生一个汇编文件code.c

    3.3数据格式  

    char

    字节

    b

    1

    short

    w

    2

    int

    双字

    1

    4

    long int

    双字

    1

    4

    long long int

    4

    char*

    双字

    1

    4

    float

    单精度

    s

    4

    Double

    双精度

    l

    8

    long double

    扩展精度

    t

    10/12

    3.4访问信息

       1.操作数指示符类型:立即数、寄存器、寄存器

       2.数据传送指令

    指令

    效果

    描述

    MOV      S,D

    S<-D

    传送

    movb

    movw

    movl

    传送字节

    传送字

    传送双字

    MOVS     S,D

    D<-符号扩展(S)

    传送符号扩展的字节

    MOVZ     S,D

    D<-零扩展(S)

    传送零扩展的字节

    3.5算术和逻辑操作(20135315韩玉琪的博客)

       1.加载有效地址:leal实际上是movl的变形,为存储器引用产生指针

       2.一元操作和二院操作:1)++,- -;2)+=

    • 一元操作
    • - INC          加1
    • - DEC          减1
    • - NEG          取负

    - NOT          取补

    • 只有一个操作数,既是源又是目的,可以是一个寄存器,或者存储器位置。
    • 二元操作
    • - ADD          加
    • - SUB          减
    • - IMUL         乘
    • - XOR          异或
    • - OR           或

    - AND          与

    • 第一个操作数可以是立即数、寄存器或者存储器位置
    • 第二个操作数既是源也是又是目的。可以是寄存器或者存储器位置,但是不能同时是存储器位置。
    • 注意操作的顺序:

       第二个操作数 操作符 第一个操作数

       3.移位操作:>>,<<

    • 先给出移位量,第二项给出要移位的数值。
    • - SAL          左移
    • - SHL          左移(等同于SAL)
    • - SAR          算术右移     

    - SHR          逻辑右移     

    • 源操作数(移位量):立即数或者放在单字节寄存器元素%cl中。
    • 目的操作数:一个寄存器或是一个存储器位置。

      

    4.特殊算术操作

    • 乘法
    • 乘积截断
    •    imull 双操作数

       - 从两个32位操作数产生一个32位的乘积。

    • 乘积不截断
    •    mull  无符号数乘法
    •    imull 有符号数乘法
    •    - 要求一个参数必须在寄存器%eax中,另一个作为指令的源操作数给出。

       - 乘积的高32位在%edx中,低32位在%eax中。

    • 除法
    • 有符号除法
    •    idivl 操作数
    •    - 将DX:AX中的64位数作为被除数,操作数中为除数

       - 结果:商在AX中,余数在DX中。

    • 无符号除法
    •    divl指令

       - 通常会事先设定寄存器%edx为0.

    3.6控制

       1.条件码:

       CF:进位标志   ZF:零标志    SF:符号标志  OF:溢出标志

       2.访问条件码 

    • SET指令:执行比较指令,根据计算t=a-b的结果设置条件码 

    3.跳转指令及其编码:jmp *%eax

    • 无条件跳转
    • 直接跳转:跳转目标是作为指令的一部分编码的。
    • 间接跳转:跳转目标是从寄存器或存储器位置中读出的。

       4.条件传送指令(参考资料20135202闫佳歆博客)

    • 将条件表达式和语句从c语言翻译成机器语言,最常用的方式就是结合有条件和无条件跳转。
    • if-else 的汇编结构
    • 通用形式模板
    •    if(test-expr)
    •          then-statement
    •    else
    •          else-statement
    •  

       (注:test-expr     整数表达式[假/真])

    • 汇编实现形式
    •    t = test-expr;
    •    if (!t)
    •          goto false;
    •    then-statement
    •    goto done;
    •    false:
    •          else-statement

       done:

       5.switch语句

    3.7过程

       1.栈帧结构:机器用栈帧来传递过程参数、存储返回信息、保存寄存器用于以后的回复以及本地存储。为单个过程分配的那部分栈称为栈帧

       2.帧指针:%ebp,栈指针:%%esp

       3.转移控制

          call  Label         过程调用

          call  *Operand      过程调用

          leave               为返回准备栈

          ret                 从过程调用中返回

       4.寄存器使用惯例

          1).%eax、%edx、%ecx  调用者保存

          2).%ebx、%esi、%edi  被调用者保存

       5.递归过程:递归调用一个函数本身与调用其他函数是一样的。相互调用更为复杂

    问题:

    1.比较指令cmp和减法指令sub有何不同?

     sub d,s   是d-s,结果送回d中,即送回目的操作数中。

     cmp d,s   也是d-s,但结果不送回目的操作数中,是利用减法进行两个数值的比较。

      作业

    • main.c:

    • 汇编代码:

    • 用vi查看编译器指令:

    • 删除gcc产生代码中以"."开头的编译器指令后:

    • 分析:
    • main函数保存%ebp,并设置新的帧指针。

      	pushl	%ebp
      	movl	%esp,%ebp
    • 分配4字节的栈空间

      	subl	$4,%esp
    • 设置 arg1=8

      	movl	$8,(%esp)
    • call调用fh
    • fh被调用,初始化帧指针,分配栈空间。
    • 将(%esp)中的8给 %eax,即存入栈中

      	movl	%eax,(%esp)
    • call调用gh
    • gh被调用,初始化栈指针,分配栈空间
    • 将 %eax 与立即数 3 相加

      	add		$3,%eax
    • 在gh结束前弹栈

      	popl	%ebp
    • ret返回fh中call的调用位置
    • fh也结束,return返回main中call调用的位置
    • main继续 %eax 加1的操作

      	addl	$1,%eax
    • leave为返回准备栈,相当于%ebp出栈,最后ret结束。

  • 相关阅读:
    PHP全部手册
    你必须收藏的GitHub技巧
    PV和并发
    api接口
    LeetCode 14. 最长公共前缀
    LeetCode 1037. 有效的回旋镖
    LeetCode 242. 有效的字母异位词
    LeetCode 151. 翻转字符串里的单词
    LeetCode 22. 括号生成
    LeetCode 面试题05. 替换空格
  • 原文地址:https://www.cnblogs.com/20135207oneking/p/4869948.html
Copyright © 2020-2023  润新知