3.5

本文详细介绍了x86汇编中的算术、逻辑及移位运算,包括加载有效地址、一元、二元运算和移位操作。通过实例解析了各种指令的使用,如leal、incl、subl、sal和sar等,并通过练习题加深了读者的理解。此外,还讨论了汇编代码与C语言代码的对应关系,以及特殊的算术运算,如64位运算和除法运算。
摘要由CSDN通过智能技术生成

一、算术及逻辑运算

图3.7列出了一些整数和逻辑运算。大多数操作都以一类指令的形式给出,因为指令可以具有不同操作数大小的不同变体。例如,指令类add包含三条加法指令:addb、addw和addl,分别是字节、字和双字的相加。实际上,上图所示的每个指令类都有对字节、字和双字数据进行操作的指令。操作分为四组:加载有效地址、一元、二进制和移位。二元运算有两个操作数,而一元运算有一个操作数。

在这里插入图片描述

1.1 载入有效地址

加载有效地址指令leal实际上是movl指令的一个变体。它从内存读取内容到寄存器,但它并没有读取内存某处存储的数据,而是读取了内存地址本身。在图3.7中,我们使用C地址运算符&S(C语言中使用&来表示读取地址信息)来表示这个计算。这个指令可以用来为以后的内存引用生成指针。此外,它还可以用来简洁地描述常见的算术运算。例如,如果寄存器%edx包含值x,则指令leal 7(%edx, %edx, 4), %eax将寄存器%eax设置为5x+7。注意,这个指令的目标操作数必须是寄存器。

练习:

假设寄存器%eax存储了值x,寄存器%ecx存储了值y。填充下执行如下指令后寄存器%edx的值:
在这里插入图片描述
答案:

  • 6+x
  • x+y
  • x+4y
  • 7+9x
  • 10+4y
  • 9+x+2y

1.2 一元及二元运算

第二组中的操作是一元操作,单个操作数同时作为源和目标。此操作数可以是寄存器或内存位置。例如,incl(%esp)指令执行后,堆栈顶部的4字节元素会自增1。

第三组由二进制操作组成,其中第二个操作数用作源操作数和目标操作数。这种语法类似C赋值运算符,例如x+=y。但注意,第一个操作数是源操作数,第二个操作数是目标操作数。例如,指令subl %eax,%edx将寄存器%edx减去%eax中的值。第一个操作数可以是立即数、寄存器或内存位置。第二个可以是寄存器或内存位置。但是,与movl指令一样,两个操作数不能都是内存位置。

练习:

假设如下的内存地址和寄存器存储了下列信息:
在这里插入图片描述
在下表中填写指令的目标地址以及运算结果:
在这里插入图片描述

DestinationValue
0x1000x100
0x1040x98
0x10C0x110
0x1080x14
%ecx0x0
%eax0xFD

1.3 移位运算

最后一组由移位操作组成,首先给出移位量,然后给出要移位的值。我们可以进行算术右移和逻辑右移。移位量被编码为单个字节,因为只有0到31之间的移位量是可能的(我们只需要使用移位量的低五字节)。移位量以立即数形式给出,或在单字节寄存器元素%cl中给出。如图3.7所示,左移位指令有两个名称:sal和shl。两者的效果相同,从右边填充零。右移位指令的不同之处在于sar执行算术移位(用符号位的副本填充),而shr执行逻辑移位(用零填充)。移位操作的目标操作数可以是寄存器或内存位置。我们将图3.7中两种不同的右移操作表示为 > > A >>_A >>A(算术)和 > > L >>_L >>L(逻辑)。

练习:

假设我们要为如下的C函数生成汇编代码:

在这里插入图片描述

下面给出了程序主题框架,需要我们填充程序的空缺部分(也就是移位部分),注意右移应该按照进行算术右移:
在这里插入图片描述
答案:

  • sall 2,%eax
  • sarl %cl,%eax

1.4 补充:汇编代码和C代码的对应

我们看到,图3.7中所示的大多数指令都可以用于无符号数或有符号补码运算。只有右移需要区分有符号和无符号数据的指令。

下图展示了一个执行算术运算的函数以及对应的汇编代码。函数参数x,y,z存储在据寄存器%ebp偏移8,12,16处:
在这里插入图片描述
我们可以看到,汇编代码指令的出现顺序与C源代码不同,同时可能出现几个汇编指令组合起来实现C语言语句的情况。

练习:


下图给出了C语言函数及对应的汇编代码,其中C语言实现的部分是空缺的,我们需要根据汇编代码填充C语言代码的功能:

在这里插入图片描述
在这里插入图片描述

  • x^y
  • t1>>3
  • ~t2
  • t3-z

1.5 特殊的算术运算

下图展示了支持用两个32位值生成64位结果的操作数,同时包括了除法运算:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值