信息的表示和处理 | 汇编语言指令

更新于 3月25日  约 4 分钟

算数运算和逻辑运算的汇编语言指令

地址运算指令:leaq

  • 由于在X86的64位系统中地址均为64位,所以以q作为后缀

QQ图片20200323161330.png

  • 源操作数一般为类似寻址模式的四元组,用于进行地址表达式计算
  • 目标操作数一般为寄存器,用于存放地址表达式运算的结果
  • 基本用法
  1. 设计初衷:计算数组某个下标的地址
  2. 拓展应用:乘法运算可以用地址运算指令进行优化。因为乘法对于处理器来说非常耗时,而加减移位运算速度远远高于乘除

QQ图片20200323161601.png

3、总结:
(1)lea和mov指令的区别:mov指令是把计算得到的地址所存储的值放到目标寄存器中;lea仅仅是把地址算出来,然后将这个地址赋值给目标操作数,即lea不会对内存进行任何访问
(2)lea在编译器使用过程中,由于不进行内存访问,所以可用来进行算数运算,可模拟变量与常数间的运算

双指令数操作

QQ图片20200325091505.png

单操作数指令

算数运算实例

  • 第一条指令为何用leap不用addp:add指令是两操作数的指令,结果必定会覆盖一个操作数,而x、y后边还会用到;lea地址运算指令可在多个寄存器间完成运算,既做了运算,又把加法结果放到新的寄存器中,不破坏原寄存器的值
  • 第二条指令为何用add:t1仅有这一次使用,覆盖掉合理,且减少了寄存器的使用数量
  • 汇编语言中固定用rax寄存器保存返回值
  • 汇编语句与高级语言不一定是一对一的关系,可能是一对多,可能是多对一。语句顺序不一定相同,但保证运行结果相同
  • 不要认为声明变量就会浪费系统内存,编译器可以合理分配寄存器,让局部变量优先存储到寄存器中。(因为寄存器速度比内存速度快得多,在寄存器中可直接参与运算,而内存中则要搬用到CPU中后才能进行运算,故而编译器优先把局部变量放在寄存器中)

逻辑运算实例

  • mask变量的运算在汇编语言指令中不存在:常量计算在编译阶段完成。参与运算的全为常量,不涉及任何变量,这样的计算过程由编译器在编译阶段就已经完成计算
  • 最后运算为何使用32位指令:在X86的64位处理器上执行32位指令时,意味着最后目标寄存器的高32位会被清零(64位处理器设计数据通路时使用这种方法来兼容32位处理器)。而mask值为8185,在高32位的值均为0,参与与运算时得到结果的高32位也一定为零,因此用32位指令不影响结果。
关注公众号,让我们携手共进0.5.jpg
阅读 77更新于 3月25日

推荐阅读
目录