写在前面
如图为x86-64的一些整数和逻辑操作。这里面大多指令都有各种带不同大小操作数的变形。eg:ADD由四条加法指令组成: addb、addw、addl和addq,分别是字节加法、字加法、双字加法和四字加法;lea指令变种(按大小分类):leaw 、leal、leaq,分别是字加法、双字加法和四字加法。
这些操作被分为四组:加载有效地址、一元操作、二元操作和移位。其中一元操作有一个操作数,二元操作有两个操作数。
加载有效地址leaq
leaq S,D
leaq:形式上是从内存读数据到寄存器,实际上是将有效地址写入到目的操作数。
eg:
c语言
long scale(long x,long y,long z){
long t = x +4* y + 12*Z;
return t;}
编译时,该函数的算术运算以三条leaq指令实现:
long scale(long x, long y,long z)
x in %rdi, y in %rsi,z in %rdx
scale:
leaq (%rdi,%rsi,4),%rax //x+4*y
leaq (%rdx, %rdx,2),%rdx //z +2*z =3*z
leaq (%rax,%rdx,4), %rax //(x+4*y)+4*(3*z)=x +4*y +12*z
ret
一元操作和二元操作
一元操作
一元操作只有一个操作数,该操作数即使源操作数又是目的操作数,该操作数可以是一个寄存器,也可以是一个内存位置。
eg:decq (%rsp) //使栈顶的8字节元素-1 类似于C语言中的--
incq (%rsp) //使栈顶的8字节元素+1 类似于C语言中的++
二元操作
二元操作有两个操作数,其中第二个操作数既是源操作数又是目的操作数。这种语法类似于C语言中的赋值运算符,例如x-=y。
第一个操作数源操作数可以是立即数、寄存器或是内存位置。
第二个操作数目的操作数可以是寄存器或是内存位置。注意,当第二个操作数为内存地址时,处理器必须从内存读出值,执行操作,再把结果写回内存。
移位操作
移位操作,第一项先给出移位量,然后第二项给出的是要移位的数;分为算术移位和逻辑移位。
第一项移位量可以是一个立即数,或者放在单字节寄存器%cl中。(注:只允许以这个特定的寄存器作为操作数)。
左移指令有两个名字:SAL和SHL。两者的效果是一样的,都是将右边填上0。
右移指令不同,SAR执行算术移位(填上符号位),而SHR执行逻辑移位(填上0)。
移位操作的目的操作数可以是一个寄存器或是一个内存位置。
学习自《深入理解计算机系统》