机器级操作:算术和逻辑操作 gaunthan Posted on May 14 2016 ? Assembly Instruction ? ## 概述 下图列出了一些整数和逻辑操作。大多数操作都分成了指令类,这些指令类有各种带不同大小操作数的变种(只有leal没有其他大小的变种,而其他的都有对字节、字和双字数据进行操作的指令),分为四组:加载有效地址、一元操作、二元操作和移位。具体见下图:  上图中使用$>>_A$和$>>_L$来分别表示算术右移和逻辑右移。另外,需要注意的是这里的操作数顺序与AT&T格式的汇编代码中的相反。 ## 加载有效地址 **加载有效地址**(load effective address)指令`leal`实际上是`movl`指令的编写。它的指令形式是从存储器读取数据到寄存器,但实际上它根本就没有引用存储器。它的第一个操作数看上去是一个存储器引用,但该指令并不是从指定的位置读入数据,而是将有效地址写入到目的操作数。 例如,如果寄存器edx的值为x,那么指令`leal 7(%edx, %edx, 4), %eax`将设置寄存器eax的值为`5x + 7`。编译器经常发现leal的灵活用法,根本与有效地址计算无关(如某些时候用来代替乘法)。目的操作数必须是一个寄存器。 ## 一元操作和二元操作 第二组中的操作是一元操作,它只有一个操作数,既是源又是目的。这个操作数可以是一个寄存器,也可以是一个存储器位置。 第三组是二元操作,其中,第二个操作数既是源又是目的。第一个操作数可以是立即数、寄存器或是存储器位置。第二个操作数可以是寄存器或是存储器位置。不过,同movl指令一样,两个操作数不能同时是存储器位置。 ## 移位操作 最后一组是移位操作,先给出移位量,然后第二项给出的是要移位的操作数。移位量用单个字节编码,因此只允许进行0到31位的移位(只考虑移位量的低5位)。移位量可以是一个立即数,或者放在单字节寄存器中。移位操作的目的操作数可以是一个寄存器或是一个存储器位置。 * 左移 左移指令有两个名字:SAL和SHL。两者的效果是一样的,都是将右边填上0。 * 右移 右移指令不同,SAR执行算术移位(填上符号位),而SHR执行逻辑移位(填上0)。 ## 特殊的算术操作 下图表述的指令支持产生两个32位数字的全64位乘积以及整数除法:  * 乘法 乘法指令都要求一个参数必须在寄存器%eax中,而另一个作为指令的源操作数给出。然后乘积存放在寄存器%edx(高32位)和%eax(低32位)中。 * 除法 除法指令将寄存器%edx(高32位)和%eax(低32位)中的64位数作为被除数,而除数作为指令的操作数给出。指令将商存储在寄存器%eax中,将余数存储在寄存器%edx中。 ## References - RandalE.Bryant, DavidR.O’Hallaron, 布赖恩特,等. 深入理解计算机系统[M]. 机械工业出版社, 2011. 赏 Wechat Pay Alipay 机器级操作:访问信息 存储器的越界引用和栈缓冲区溢出