算数运算和逻辑运算的汇编语言指令
地址运算指令:leaq
- 由于在X86的64位系统中地址均为64位,所以以q作为后缀
- 源操作数一般为类似寻址模式的四元组,用于进行地址表达式计算
- 目标操作数一般为寄存器,用于存放地址表达式运算的结果
- 基本用法
- 设计初衷:计算数组某个下标的地址
- 拓展应用:乘法运算可以用地址运算指令进行优化。因为乘法对于处理器来说非常耗时,而加减移位运算速度远远高于乘除
3、总结:
(1)lea和mov指令的区别:mov指令是把计算得到的地址所存储的值放到目标寄存器中;lea仅仅是把地址算出来,然后将这个地址赋值给目标操作数,即lea不会对内存进行任何访问
(2)lea在编译器使用过程中,由于不进行内存访问,所以可用来进行算数运算,可模拟变量与常数间的运算
双指令数操作
单操作数指令
算数运算实例
- 第一条指令为何用leap不用addp:add指令是两操作数的指令,结果必定会覆盖一个操作数,而x、y后边还会用到;lea地址运算指令可在多个寄存器间完成运算,既做了运算,又把加法结果放到新的寄存器中,不破坏原寄存器的值
- 第二条指令为何用add:t1仅有这一次使用,覆盖掉合理,且减少了寄存器的使用数量
- 汇编语言中固定用rax寄存器保存返回值
- 汇编语句与高级语言不一定是一对一的关系,可能是一对多,可能是多对一。语句顺序不一定相同,但保证运行结果相同
- 不要认为声明变量就会浪费系统内存,编译器可以合理分配寄存器,让局部变量优先存储到寄存器中。(因为寄存器速度比内存速度快得多,在寄存器中可直接参与运算,而内存中则要搬用到CPU中后才能进行运算,故而编译器优先把局部变量放在寄存器中)
逻辑运算实例
- mask变量的运算在汇编语言指令中不存在:常量计算在编译阶段完成。参与运算的全为常量,不涉及任何变量,这样的计算过程由编译器在编译阶段就已经完成计算
- 最后运算为何使用32位指令:在X86的64位处理器上执行32位指令时,意味着最后目标寄存器的高32位会被清零(64位处理器设计数据通路时使用这种方法来兼容32位处理器)。而mask值为8185,在高32位的值均为0,参与与运算时得到结果的高32位也一定为零,因此用32位指令不影响结果。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。