汇编语言(三) - 通用数据处理指令

简介

熟悉IA-32处理器通用的基本指令

  • 数据传送指令
  • 算术运算指令
  • 逻辑运算指令
  • 移位操作指令

掌握指令功能和编程应用

学习指令的注意事项

指令的功能

  • 指令能够实现何种操作
  • 指令助记符是指令功能的英文单词或其缩写形式

指令支持的寻址方式

  • 指令中的操作数可以采用何种寻址方式

指令对标志的影响

  • 指令执行后是否对各个标志位有影响,以及如何影响

其他方面

  • 指令执行时的约定设置
  • 必须预置的参数
  • 隐含使用的寄存器
80x86指令系统

80x86高档微处理器包含如下指令系统

  • 通用指令集(CPU)
  • 浮点指令集(FPU浮点处理器)
  • MMX指令集(多媒体扩展指令集)
  • SSE和SSE2指令集(流式单指令多数据扩展指令集)
指令系统

计算机所能执行的各种代码指令的集合
80x86cpu的通用指令分为6大类

  • 数据传送指令
  • 算术运算指令
  • 逻辑运算指令
  • 字符串处理指令
  • 控制与转移指令
  • 处理机控制指令

1.数据传送类指令

数据传送

  • 把数据从一个位置传送到另一个位置
  • 计算机中最基本的操作
  • 程序设计中最常使用的指令
  • 除标志寄存器传送指令外,均不影响标志位

全面而准确地理解每条指令的功能和应用 是编写汇编语言程序的关键 也是理解处理器如何进行数据处理的核心

数据传送类指令

数据传送指令

  • MOV (MOVe ) 传送
  • MOVSX(MOVe with Sign-eXtend)
  • MOVZX(MOVe with Zero-eXtend)
  • XCHG互换指令

堆栈操作指令

  • PUSH 入栈 – POP 出栈

地址传送指令

  • LEA(Load effictive Address)装入有效地址

换码指令

  • XLAT 换码

标志传送指令

  • LAHF(Load AH with Flags) 标志寄存器低8位传送AH
  • SAHF(Store AH into Flags) AH寄存器传送到标记寄存器低8位
1.1 通用数据传送指令

提供方便灵活的通用数据传送操作
主要有传送MOV和交换XCHG指令
在这里插入图片描述
1.传送指令MOV
把一个字节、字或双字的操作数从源位置传送至目的位置
在这里插入图片描述
MOV指令限制的情况
源操作数和目的操作数

  • 数据类型必须一致
  • 不能同时使用存储器寻址方式

目的操作数

  • 不可以是:立即数,EIP,IP和CS

段寄存器

  • 不能相互传送
  • 立即数不能直接传送
部分限制的解决

在这里插入图片描述

MOVZX 带0(零位)扩展传送指令
适用于无符号整数,标志位无变化。
源操作数中的数据复制到目的操作数,并将0扩展到16bit(32bit)
在这里插入图片描述
MOVSX 带符号扩展传送指令
源操作数中的数据复制到目的操作数,将符号位扩展到16bit或32bit.
在这里插入图片描述

2.交换指令XCHG
将源操作数和目的操作数内容交换
XCHG reg,reg
XCHG reg,mem
XCHG mem,reg

  • 通用寄存器与通用寄存器之间
  • 通用寄存器与存储器之间
//交换
 mov ax,val1
 xchg ax,val2
 mov val1,ax

空操作指令NOP(XCHG EAX,EAX)

  • 操作码 90H
  • 实现短时间延时
  • 临时占用代码空间
1.2 堆栈及操作

特殊的内存区,暂时存放数据和地址
操作方式:后进先出(LIFO)/先进后出 (FILO)
处理器用硬件支持堆栈数据结构
堆栈指针ESP

  • 随有关指令自动增减
  • 属于专用寄存器
  • 有通用寄存器灵活应用特点
    可赋值: sub esp,4 mov esp,ebp
    可寻址: mov ebx,[esp+4]
    在这里插入图片描述
    IA-32处理器堆栈操作
    在这里插入图片描述
    入栈和出栈指令
Push reg16 		POP	reg16
Push mem16 		POP	mem16
Push seg 		POP reg32
Push reg32 		POP mem32
Push mem32 
Push imm32

ESP操作规则:

  1. 字为2,双为4
  2. 入先-,出后+

push操作示意图

在这里插入图片描述
pop操作示意图
在这里插入图片描述
Pushfd与Popfd

  • Pushfd将EFLAGS寄存器 内容压入堆栈
  • Popfd将栈顶单元内容弹 出到EFLAGS
  • EFLAGS寄存器为标记寄存器
    在这里插入图片描述
    通用寄存器入栈、出栈
    Pushad
  • EAX,ECX,EDX,EBX,ESP,EBP,E SI,EDI顺序将32位寄存器压 栈

Pusha

  • AX,CX,DX,BX,SP,BP,SI,DI顺 序将16位寄存器压栈

在这里插入图片描述
堆栈不平衡问题
在这里插入图片描述
堆栈的应用
使用堆栈的指令

  • 堆栈操作类指令,例如PUSH,POP
  • 过程调用CALL和返回RET

堆栈的应用

  • 临时存放寄存器数据,以便随时恢复
  • 执行CALL时,保存当前过程的返回地址
  • 调用程序与过程间传递参数,例如C/C++的函数调用
  • 过程内局部变量的临时存储区
    要点:
  • 保持堆栈平衡,例如入栈和出栈成对使用

字符串反转
在这里插入图片描述

1.3 地址传送指令

获取存储器操作数的偏移地址

  • LEA r16/r32,mem

类似于地址操作符OFFSET的作用

  • LEA指令在指令执行时计算出偏移地址,运行时
  • OFFSET操作符在汇编阶段取得变量的偏移地址,编译时

优缺点

  • OFFSET无需在执行时计算、指令执行速度更快
  • LEA指令能获取汇编阶段无法确定的偏移地址
lea esi, var
mov edi, offset var

地址传送程序

;数据段 
dvar dword 41424344h 
;代码段 
mov eax,dvar 
lea esi,dvar 
mov ebx,[esi] 
mov edi,offset dvar 
mov ecx,[edi] 
lea edx,[esi+edi*4+100h]
1.4 换码指令

XLAT指令功能:AL←[EBX+AL]

  • 将EBX指定的缓冲区中
  • AL指定的位移处的一个字节数据
  • 取出赋给AL

换码指令执行前:

  • 在主存建立一个字节量表格,内含要目的代码
  • 表格首地址存放于EBX
  • AL存放相对表格首地址的位移量

换码指令执行后:

  • 将AL寄存器的内容转换为目标代码
1.5 标志传送指令LAHF,SAHF

LAHF将EFLAGS的低字节复制到AH寄存器
SAHF将AH寄存器的内容复制到EFLAGS的低字节
影响的标志位:SF、ZF、AF、PF、CF标志
标志位操作符

  • CLC 清除CF位(CF=0) STC 设置CF位(CF=1) CMC取反CF位

应用举例

.data
saveflags	byte	?
.code
lahf
mov	saveflags,ah
......
mov	ah,saveflags
sahf

2.算术运算类指令

算术运算

  • 对数据进行加减乘除
  • 基本的数据处理方法
  • 加减运算的进位、借位、溢出状态也是结果的一部分

关注对标志的影响

  • 掌握:加法和减法指令
  • 熟悉:乘法和除法指令
  • 理解:零位扩展和符号扩展
2.1 状态标志

状态标志是处理器最基本的标志
用途

  • 作为加减运算和逻辑运算的辅助结果
  • 构成各种条件,实现程序分支

在这里插入图片描述
进位标志CF(Carry Flag)
CF=1

  • 加减运算结果的最高 有效位有进位(加法) 或借位(减法)时

用途

  • 判断无符号整数加减 结果是否超出表达范 围

如何改变CF值?

  • STC 置位CF = 1
  • CLC 清位CF = 0
  • CMC 变反CF位
    在这里插入图片描述
    溢出标志OF(Overflow Flag)
    OF=1
  • 有符号数加减结果有溢出

用途

  • 判断有符号整数加减结果是否超出表达范围

处理器硬件判断规则

  • 最高位和次高位同时有进位或同时无进位,无溢出
  • 最高位和次高位进位状态不同,有溢出

人工判断

  • 当两个相同符号数相加(两个不同符号数相减),而运算结果 的符号与原数据符号相反时,产生溢出

在这里插入图片描述
进位和溢出的区别
CF反映无符号整数运算结果是否超出范围

  • 有进位,加上进位或借位后运算结果仍然正确

OF反映有符号整数运算结果是否超出范围

  • 有溢出,运算结果已经不正确

处理器按照无符号整数求得结果

  • 设置进位标志CF
  • 设置溢出标志OF

程序员决定

  • 操作数是无符号数,关心进位CF
  • 操作数是有符号数,注意溢出OF

零标志ZF(Zero Flag)

运算结果为0,则ZF=1,否则ZF=0
结果是0, ZF标志不是0 !
在这里插入图片描述
符号标志SF(Sign Flag)
运算结果最高位为1,则SF=1;否则SF=0
最高位=符号位=SF
在这里插入图片描述
奇偶标志PF(Parity Flag)
当运算结果最低字节中“1”的个数为零或偶数时, PF=1;否则PF=0 (仅最低8位“1”的个数
在这里插入图片描述

2.2 加法指令

加法指令 ADD
带进位加法指令 ADC
增量指令 INC

  • INC不影响CF,影响其他标志位
  • ADD,ADC按定义设置全部状态标志位

数据传送类指令不影响(=不改变)状态标志
加法和减法指令根据结果按定义改变状态标志

1. 加法指令ADD
目的操作数加源操作数,和送到目的操作数

  • ADD reg,imm/reg/mem ;reg←reg+imm/reg/mem
  • ADD mem,imm/reg ;mem←mem+imm/reg

按照定义影响6个状态标志位(CF,OF,SF,ZF,AF,PF)

  • mov eax,0aaff7348h ;EAX=AAFF7348H
  • add al,27h
  • add ax,3fffh
  • add eax,88000000h

2. 带进位加法指令ADC

两个操作数相加,再加CF,结果送目的操作数

  • ADC reg,imm/reg/mem ;reg←reg+imm/reg/mem+CF
  • ADC mem,imm/reg ;mem←mem+imm/reg+CF

用于与ADD指令相结合实现多精度数的加法

  • 先将两个操作数的低32位相加(用ADD指令)
  • 再加高位部分、并将进位加到高位(用ADC指令)
    64位数据相加程序
mov eax,dword ptr qvar1 ;取低32位 
add eax,dword ptr qvar2 ;加低32位,设置CF
 mov edx,dword ptr qvar1+4 ;取高32位 
 adc edx,dword ptr qvar2+4 ;加高32位,同时加CF

3. 增量指令INC
对操作数加1(增量)再将结果返回原处

  • INC reg/mem ;加1:reg/mem←reg/mem+1
    用于计数器和地址指针的调整
    不影响进位CF标志,影响其他状态标志位
inc ecx 
inc dword ptr [ebx] 
inc wvar
2.3 减法指令

减法指令 SUB
带借位减法指令 SBB
减量指令 DEC
求补指令 NEG
比较指令 CMP

  • 除DEC不影响CF标志外
  • 其他按定义影响全部状态标志位

1. 减法指令SUB
目的操作数减源操作数,差送到目的操作数

  • SUB reg,imm/reg/mem ;reg←reg-imm/reg/mem
  • SUB mem,imm/reg ;mem←mem-imm/reg

按照定义影响6个状态标志位

mov eax,0aaff7348h ;EAX=AAFF7348H 
sub al,27h 
sub ax,3fffh 
sub eax,0bb000000h

2. 带借位减法指令SBB
目的操作数减源操作数,再减CF,结果送目的操作数

  • SBB reg,imm/reg/mem ;reg←reg-imm/reg/mem-CF
  • SBB mem,imm/reg ;mem←mem-imm/reg-CF

用于与SUB指令相结合实现多精度数的减法

  • 先将两个操作数的低32位相减(用SUB指令)
  • 然后减高位部分、并减去借位(用SBB指令)
    3. 减量指令DEC
    只有一个操作数:寄存器或存储单元
    对操作数减1(减量)再将结果返回原处
  • DEC reg/mem ;减1:reg/mem←reg/mem-1

用于计数器和地址指针的调整
不影响进位CF标志,影响其他状态标志位
例如

dec cx 
dec byte ptr [ebx] 
dec wvar

4. 求补指令NEG
对操作数执行求补运算,即用零减去操作数

  • NEG reg/mem ;reg/mem←0-reg/mem

对标志的影响与用零作减法的SUB指令一样
可用于对负数求补码或由补码求其绝对值

mov ax,0ff64h 
neg al 
sub al,9dh 
neg ax 
dec al 
neg ax

5. 比较指令CMP
将目的操作数减去源操作数,差值不回送目的操作数
按照减法结果影响状态标志

  • CMP reg,imm/reg/mem ;reg-imm/reg/mem
  • CMP mem,imm/reg ;mem-imm/reg

根据标志状态获知两个操作数的大小关系
给条件转移等指令使用其形成的状态标志

2.4 乘法和除法指令

IA-32处理器针对无符号数和有符号数采用不同的 乘法和除法指令
有符号数指令前用I(sIgned)表示
隐含使用EAX(和EDX)寄存器

255的机器表示FF  
-1的机器表示FF 
-1×-1 = 1 
FF×FF = 1 ?

1. 乘法指令
无符号数:mul src
有符号数: imul src

指令类型操作数组合及功能举例
无符号数乘法
有符号乘法
AX = AL * r8 / m8
DX.AX = AX * r16 / m16
EDX.EAX = EAX * r32 / m32
mul bl
imul bx
mul exb
双操作数乘法
IMUL dest, src
r16 = r16 * r16 / m16 / i8 / i16
r32 = r32 * r32 / m32 / i8 / i32
imul eax, 10
imul ebx ,ecx
三操作数乘法
IMUL dest, src, imm
r16 = r16/m16 * i8 / i16
r32 = r32 / m32 * i8 / i32
imul ax, bx ,-2

imul eax,dword ptr [esi+8],5
2.除法指令
无符号:div
有符号:idiv
div指令除法溢出

  • 除数为0
  • 字节除时商超过8位
  • 字除时商超过16位
  • 双字除时超过32位

idiv指令除法溢出

  • 除数为0
  • 字节除时商不在-128~127范围内
  • 字除时商不在-32768~32767范围内
  • 双字除时商不在-231~231-1范围内

除法错溢出产生0号内部中断
除法指令

指令操作数组合及功能举例
无符号除法:
div src
AL < ---- AX / r8/m8 的商
AH < ---- AX / r8/m8 的余数
AX < ---- DX.AX / r16/m16 的商
div bl
div ebx
有符号除法:
idiv src
AX < ---- DX.AX / r16/m16 的余数
EAX < ---- EDX.EAX / r32/m32 的商
EAX < ---- EDX.EAX / r32/m32 的余数
idiv ebx

2.5 符号扩展指令
CBW

  • 将AL中数据符号扩展到AX中

CWD

  • 将AX中数据符号扩展到DX和AX中

CWDE

  • 将AX中数据符号扩展到EAX中

CDQ

  • 将EAX中数据符号扩展到EDX和EAX中

十进制调整指令
压缩BCD码调整指令

  • DAA 十进制加法调整
  • DAS 十进制减法调整

非压缩BCD码调整指令

  • AAA ASCII码加法调整
  • AAS ASCII码减法调整
  • AAM ASCII码乘法调整
  • AAD ASCII码除法调整

3.位操作类指令

计算机中最基本的数据单位是二进制位
针对二进制位进行操作、实现位控制的指令

  • 逻辑运算指令
  • 移位指令
  • 循环移位指令

进行1位或若干位处理,采用位操作类指令

3.1 逻辑运算指令

逻辑与指令 AND
逻辑或指令 OR
逻辑非指令 NOT
逻辑异或指令 XOR
测试指令 TEST
对标志位的影响:

  • 除NOT指令不影响标志外,其他逻辑指令
  • 使OF=CF=0
  • 根据结果按定义影响ZF、SF和PF

1. 逻辑与指令AND
逻辑与(逻辑乘)运算规则:

  • 两位都是逻辑1,则结果是1;否则,结果是0

逻辑与指令AND:

  • 按位进行逻辑与,结果返回目的操作数
AND reg,imm/reg/mem 
;reg←reg ^ imm/reg/mem 
AND mem,imm/reg 
;mem←mem ^ imm/reg

设置CF=OF=0
影响SF,ZF和PF

AND指令的屏蔽作用
清除选定的位,并保存其他位
在这里插入图片描述
小写字符转换为大写
在这里插入图片描述

2. 逻辑或指令OR
逻辑或(逻辑加)运算规则:

  • 两位都是逻辑0,则结果是0;否则,结果是1

逻辑或指令OR:

  • 按位进行逻辑或,结果返回目的操作数

在这里插入图片描述
设置CF=OF=0
影响SF,ZF和PF

OR指令的置位作用
用于设置特定为,保留其他位

  • mov al,11100011b
  • or al,00000100b
    在这里插入图片描述
    3. 逻辑非指令NOT
    逻辑非(逻辑反)运算规则:
  • 原来为0的位变成1,原来为1的位变成0

逻辑非指令NOT:

  • 按位进行逻辑非,结果返回操作数
NOT reg/mem ;reg/mem←~reg/mem

不影响状态标志位
4. 逻辑异或指令XOR
逻辑异或(逻辑半加)运算规则:

  • 两位不同(相异),则结果是1;否则,结果是0

逻辑异或指令XOR:

  • 按位进行逻辑异或,结果返回目的操作数

在这里插入图片描述
设置CF=OF=0
影响SF,ZF和PF
使用xor清除寄存器
在这里插入图片描述

XOR之指令的可逆性
与0异或的位保持不变,与1异或的位变反
与同样的操作数执行两次异或后,结果不变
在这里插入图片描述

5. 测试指令TEST
按位进行逻辑与运算,不返回逻辑与结果

TEST reg,imm/reg/mem ;reg ^ imm/reg/mem 
TEST mem,imm/reg ;mem ^ imm/reg

像AND指令一样来设置状态标志
常用于检测一些条件是否满足,一般后跟条件转移指令,目 的是利用测试条件转向不同的分支

3.2 移位指令
  • 逻辑左移指令 SHL

  • 逻辑右移指令 SHR

  • 算术左移指令 SAL

  • 算术左移指令 SAR

  • 不带进位循环左移指令 ROL

  • 不带进位循环右移指令 ROR

  • 带进位循环左移指令 RCL

  • 带进位循环右移指令 RCR

在这里插入图片描述

1. 移位指令

  • 分逻辑(Logical)和算术(Arithmetic)移位
  • 具有左移(Left)或右移(Right)操作
SHL reg/mem,i8/CL ;逻辑左移:最低位补0,最高位进入CF 
SHR reg/mem,i8/CL ;逻辑右移:最高位补0,最低位进入CF 
SAL reg/mem,i8/CL ;算术左移,与SHL是同一条指令 
SAR reg/mem,i8/CL ;算术右移:最高位不变,最低位进入CF

目的操作数:寄存器或存储单元reg/mem
后一个操作数:移位位数i8/CL

移位指令的功能和示例
在这里插入图片描述

2. 循环移位指令
循环(Rotate)移位指令要将从一端移出的位返回 到另一端形成循环
分成不带进位循环移位和带进位循环移位
分别具有左移或右移操作

ROL reg/mem,i8/CL ;不带进位循环左移指令
ROR reg/mem,i8/CL ;不带进位循环右移指令
RCL reg/mem,i8/CL ;带进位循环左移指令 
RCR reg/mem,i8/CL ;带进位循环右移指令

不带进位的循环左移指令
在这里插入图片描述

带进位的循环左移指令
在这里插入图片描述

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值