zoukankan      html  css  js  c++  java
  • CSAPP阅读笔记-汇编语言初探(算术和逻辑操作类指令)-来自第三章3.5的笔记-P128-P135

    1.算术和逻辑操作类指令分四类:加载有效地址,一元操作,二元操作和移位,如下:

    2. leaq指令,类似mov指令,它左侧的数看似是给出一个地址,在内存中从给定的地址取操作数,传给右边的目的地。但其实没有取,而是直接将左侧的数对应的地址传给了右侧的目的地。

    例子: leaq 7(%rdx,%rdx,4),%rax    

    若%rdx的值为x,则最后%rax的值为5x+7,而不是以5x+7为地址,在内存中寻址得到的操作数

    3. 第二组是一元指令,目的地为寄存器或一个内存位置,具体不用介绍,看表就好。

    4. 第三组是二元指令,第二个操作数既是源又是目的,第一个操作数可以为立即数、寄存器或内存位置,第二个操作数可以为寄存器或内存位置。

    5. 第四组是移位操作,第一个操作数是移位量,它可以是立即数或存放在%cl中,第二个操作数是要移位的数,可以是寄存器或者内存位置。当移位量存放在%cl中时,具体的移位量由移位指令的移位量级来决定,比如salb,此时23=8,则移位量由%cl的低3位决定,如%cl=0cFF,则移位量为7,同理,salw移15位,sall移31位,salq移63位。而决定移位指令的移位量级的则是被移位的数的量级,比如被移位的是%rax,则用salq。

     左移指令有sal和shl,两者等价,移动后右边填0。右移指令有sar和shr,sar为算术移位,左补符号位,shr为逻辑移位,左补0。

     练习:

      xorq %rdx,%rdx

      1.它做了什么?

       答:它实现了对%rdx的置0

      2.它有什么其它的汇编表达形式?

       答:movq $0,%rdx

      3.比较这两种操作分别编码的字节长度

       答:xorq占3个字节,movq这里占7个字节,所以一般使用xorq来实现置0操作,由于任何更新低位4字节的指令都会把高位4字节置为0

           所以可以用 xorl %edx,%edx(2字节) 和 movl $0,edx(5字节)来实现。

    6.特殊的算术操作

      1.imulq,前面提到的imulq会从两个64位的操作数产生一个128位的操作数,截取其中的64位作为结果。此时需要两个操作数。

      (注意,一个a位的操作数和一个b位的操作数,产生的乘积是a+b位的操作数) 

      2.此外,x86-64提供一系列单操作数指令,用于进行全128位运算

       mulq是无符号乘法,imulq是补码乘法,它们都是单操作数指令,另一个操作数必须存在%rax中,乘积放在%rdx(高64位)和%rax(低64位)中

       测试:

      #include <inttypes.h>

      typedef unsigned __int128 uint128_t;

      void store_uprod(uint128_t *dest,uint64_t x,uint64_t y)

      {

        *dest = x*(uint128_t)y;

      }

      此程序中,uint64_t类型由头文件inttypes.h定义,但此文件未定义128位的整数,因此使用gcc自带的unsigned __int128整数支持,为了和uint64_t保持一样的命名规律,用typedef声明成uint128_t。

      其对应的汇编代码如下:

      store_uprod:

        movq %rsi,%rax

        mulq %rdx

        movq %rax,(%rdi)

        movq %rdx,8(%rdi)

        ret

      这里把乘积的低8字节存在了%rdi寻址的内存地址,高8字节存在了更大的地址,所以这里是小端法存储。

      3.同样的,也有对应的单操作数无符号除法(divq)和有符号除法(idivq),即128位除法,注意没有双操作数的除法。

       它们把%rdx(高64位)和%rax(低64位)合起来的128位作为被除数,除数则作为单操作数被给出,结果的商存在%rax中,余数存在%rdx中。

       但是,当要进行64位除法时,此时没有双操作数的除法,怎么办?

       此时会把64位的被除数存在%rax中,%rdx被设置为全0(无符号运算)或%rax的符号位(有符号运算)。设置%rdx为%rax的符号位可以用指令cqto完成,

       它不需要操作数,会自动读出%rax的符号位,并复制到%rdx的所有位。

    完毕!

  • 相关阅读:
    【Linux】项目部署
    【架构师之路】【MQ】消息队列
    【数据库】【Python】mysql
    【算法】【Python】找出字符串中重复出现的字符 并求出重复次数 且根据重复次数从大到小排列
    【Python】排序 按照list中的字典的某key排序
    Kettle Post请求webservice
    python+pytest+allure接口自动化测试框架
    Python+unittest+requests+htmlTestRunner+excel完整的接口自动化框架
    python实现栈的基本操作
    展示博客园顶部的随笔、文章、评论、阅读量统计数据
  • 原文地址:https://www.cnblogs.com/czw52460183/p/10032239.html
Copyright © 2011-2022 走看看