x86-64常用指令总结


个人博客

本文将《深入理解计算机系统》中涉及到的 x86-64 常用指令进行了总结,需要的时候方便查询

本文采取的是ATT格式的汇编代码,这是 gcc、objdump 等工具的默认格式。但是在其他一些工具里,比如说微软的工具和 Intel 的文档里,其汇编代码都是 Intel 格式的

数据格式

Intel 数据类型汇编代码后缀大小(字节)
字节b1
w2
双字l4
四字q8
单精度s4
双精度l8
  1. Intel 使用 字(word) 表示16位数据类型

  2. 汇编指令除了要指明操作对象,还要指明操作对象的数据类型及长度。为了指明操作对象的数据类型及长度,可以在指令后面加上表示数据类型的后缀,比如 movlmovq分别表示操作的对象为双字和四字,gcc 生成的汇编代码一般都有这样的一个字符后缀;但其实操作对象的长度也可以通过寄存器给出,比如说eax和rax分别表示32位和64位,因此指令后面不加后缀也是可以的

寄存器

在这里插入图片描述

%ebp%esp:栈是从高地址向低地址延伸的。每个函数的每次调用,都有它自己独立的一个栈帧,%esp总是指向当前栈帧的顶部(低地址),而%ebp通常指向当前栈帧的底部(高地址),用于在栈帧中寻址

操作数格式(寻址方式)

类型格式操作数值名称
立即数$ImmImm立即数寻址
寄存器 r a r_a raR[ r a r_a ra]寄存器寻址
存储器ImmM[Imm]绝对寻址
存储器( r a r_a ra)M[R[ r a r_a ra]]间接寻址
存储器Imm( r b r_b rb)M[Imm+R[ r b r_b rb]](基址+偏移量)寻址
存储器( r b , r i r_b,r_i rb,ri)M[R[ r b r_b rb]+R[ r i r_i ri]]变址寻址
存储器Imm( r b , r i r_b,r_i rb,ri)M[Imm+R[ r b r_b rb]+R[ r i r_i ri]]变址寻址
存储器( , r i , s ,r_i,s ,ri,s)M[R[ r i r_i ri] ⋅ s \cdot s s]比例变址寻址
存储器Imm( , r i , s ,r_i,s ,ri,s)M[Imm+R[ r i r_i ri] ⋅ s \cdot s s]比例变址寻址
存储器( r b , r i , s r_b,r_i,s rb,ri,s)M[R[ r b r_b rb]+R[ r i r_i ri] ⋅ s \cdot s s]比例变址寻址
存储器Imm( r b , r i , s r_b,r_i,s rb,ri,s)M[Imm+R[ r b r_b rb]+R[ r i r_i ri] ⋅ s \cdot s s]比例变址寻址

数据传送指令

指令效果描述
MOV  S , D \text{MOV }S, D MOV S,D D ← S D\leftarrow S DS传送
movb
movw
movl
movq
movabsp
传送字节
传送字
传送双字
传送四字
传送绝对的四字

x86-64 约定,传送指令的两个操作数不能都指向内存位置

指令效果描述
MOVZ  S , D \text{MOVZ }S, D MOVZ S,D D ← 零扩展 ( S ) D\leftarrow \text{零扩展}(S) D零扩展(S)以零扩展进行传送
movzbw
movzbl
movzwl
movzbq
movzwq
将做了零扩展的字节传送到字
将做了零扩展的字节传送到双字
将做了零扩展的字传送到双字
将做了零扩展的字节传送到四字
将做了零扩展的字传送到四字
指令效果描述
MOVS  S , D \text{MOVS }S, D MOVS S,D D ← 符号扩展 ( S ) D\leftarrow \text{符号扩展}(S) D符号扩展(S)以零扩展进行传送
movsbw
movsbl
movswl
movsbq
movswq
movslq
cltq






%rax ← \leftarrow 符号拓展(%eax)
将做了符号扩展的字节传送到字
将做了符号扩展的字节传送到双字
将做了符号扩展的字传送到双字
将做了符号扩展的字节传送到四字
将做了符号扩展的字传送到四字
将做了符号扩展的双字传送到四字
把%eax符号扩展到%rax

压入和弹出栈数据

指令效果描述
pushq S

popq D
R[%rsp] ← \leftarrow R[%rsp]-8;
M[R[%rsp]] ← \leftarrow S

D ← \leftarrow M[R[%rsp]];
R[%rsp] ← \leftarrow R[%rsp]+8
将四字压入栈


将四字弹出栈

这两个操作都会修改%rsp的值

算术和逻辑操作

指令效果描述
leaq S, DD ← \leftarrow &S加载有效地址
该指令实际上是movq指令的变形,
它的指令形式是从内存读数据到寄存器,
但实际上它没有引用内存,而是将有效地址
写入到目的操作数,
比如 leaq 7(%rdi,%rsi,4),%rax
会把%rax设置为 %rdi+4*%rsi+7
INC D
DEC D
NEG D
NOT D
D ← \leftarrow D + 1
D ← \leftarrow D - 1
D ← \leftarrow -D
D ← \leftarrow ~D
ADD S,D
SUB S,D
IMUL S,D
XOR S,D
OR S,D
AND S,D
D ← \leftarrow D + S
D ← \leftarrow D - S
D ← \leftarrow D * S
D ← \leftarrow D ^ S
D ← \leftarrow D | S
D ← \leftarrow D & S
SAL k,D
SHL k,D
SAR k,D
SHR
D ← \leftarrow D << k
D ← \leftarrow D << k
D ← \leftarrow D >>(算数) k
D ← \leftarrow D >>(逻辑) k
左移
左移(等同于SAL)
算术右移
逻辑右移

注意,ADD S,D 由四条加法指令组成,即 addb, addw, addladdq,其他指令也是如此

Intel把16字节的数称为八字(oct word)。下面是一些特殊的指令:

指令效果描述
imulq S
mulq S
R[%rdx]:R[%rax] ← \leftarrow S * R[%rax]
R[%rdx]:R[%rax] ← \leftarrow S * R[%rax]
有符号乘法,结果高64位放在%rdx,低64位放在%rax
无符号乘法,结果高64位放在%rdx,低64位放在%rax
cltoR[%rdx]:R[%rax] ← \leftarrow 符号拓展(R[%rax])将%rax符号拓展为8字,高64位放在%rdx
idivq

divq
R[%rdx] ← \leftarrow (R[%rdx]:R[%rax]) mod S
R[%rdx] ← \leftarrow (R[%rdx]:R[%rax]) ÷ \div ÷ S

R[%rdx] ← \leftarrow (R[%rdx]:R[%rax]) mod S
R[%rdx] ← \leftarrow (R[%rdx]:R[%rax]) ÷ \div ÷ S
有符号除法,将%rdx作为被除数的高64位,%rax作为被除数的低64位

无符号除法,将%rdx作为被除数的高64位,%rax作为被除数的低64位

控制指令

条件码

CPU维护着一组单个位的条件码寄存器,它们描述了最近的算数或者逻辑操作的属性,可以检查这些寄存器来执行条件分支指令。最常用的条件码有:

  • CF:进位标志,最近的操作使最高位产生了进位,可用于检查无符号操作的溢出
  • ZF:零标志,最近的操作得出的结果为0
  • SF:符号标志,最近的操作得到的结果为负数
  • OF:溢出标志,最近的操作导致一个补码溢出(正溢出获负溢出)

算术和逻辑操作列出的指令中,除了leaq,其他指令都会修改条件码寄存器

除了算数和逻辑操作指令可以改变条件码寄存器,下面的指令也可以改变:

指令基于描述
CMP S1,S2S2 - S1比较,根据 S2 - S1 的值来设置条件码寄存器
TEST S1,S2S1 & S2根据 S1 & S2 (逻辑与,不是按位与)的值来设置条件码寄存器

访问条件码

条件码通常不会直接读取,常用的使用方法有三种

  • 更具条件码的某种组合,将一个字节设置为0或者1
  • 根据条件码进行跳转
  • 有条件地传送数据

对于第一种情况,将这一整类指令称为SET指令

指令同义名效果设置条件
sete D
setne D
setz
setnz
D ← \leftarrow ZF
D ← \leftarrow ~ZF
相等/零
不等/非零
sets D
setns D
D ← \leftarrow SF
D ← \leftarrow ~SF
负数
非负数
setg D
setge D
setl D
setle D
setnle
setnl
setnge
setng
D ← \leftarrow ~(SF^OF) & ~ZF
D ← \leftarrow ~(SF^OF)
D ← \leftarrow SF^OF
D ← \leftarrow SF^OF | ZF
有符号大于
有符号大于等于
有符号小于
有符号小于等于
seta D
setae D
setb
setbe
setnbe
setnb
setnae
setna
D ← \leftarrow ~CF & ~ZF
D ← \leftarrow ~CF
D ← \leftarrow CF
D ← \leftarrow CF | ZF
无符号大于
无符号大于等于
无符号小于
无符号小于等于

跳转指令

指令同义名跳转条件描述
jmp Label
jmp *Operand
1
1
直接跳转
间接跳转
je Label
jne Label
jz
jnz
ZF
~ZF
相等
不相等
js Label
jns Label
SF
~SF
负数
非负数
jg Label
jge Label
jl Label
jle Label
jnle
jnl
jnge
jng
~(SF^OF) & ~ZF
~(SF^OF)
SF^OF
SF^OF |ZF
有符号大于
有符号大于等于
有符号小于
有符号小于等于
ja Label
jae Label
jb Label
jbe Label
jnbe
jnb
jnae
jna
~CF & ~ZF
~CF
CF
CF | ZF
无符号大于
无符号大于等于
无符号小于
无符号小于等于

条件传送指令

指令同义名跳转条件描述
cmove S,R
cmovne S,R
cmovz
cmovnz
ZF
~ZF
相等
不相等
cmovs S,R
cmovns S,R
SF
~SF
负数
非负数
cmovg S,R
cmovge S,R
cmovl S,R
cmovle S,R
cmovnle
cmovnl
cmovnge
cmovng
~(SF^OF) & ~ZF
~(SF^OF)
SF^OF
SF^OF |ZF
有符号大于
有符号大于等于
有符号小于
有符号小于等于
cmova S,R
cmovae S,R
cmovb S,R
cmovbe S,R
cmovnbe
cmovnb
cmovnae
cmovna
~CF & ~ZF
~CF
CF
CF | ZF
无符号大于
无符号大于等于
无符号小于
无符号小于等于

转移控制

指令描述
call Label
call *Operand
ret
过程调用
过程调用
从过程调用中返回
### 回答1: erlang-22.3-1.el7.x86_64.rpm是Erlang编程语言版本22.3的RPM软件包,适用于CentOS和Red Hat Enterprise Linux (RHEL)操作系统的64位版本。Erlang是一种基于函数式编程的并发编程语言,由瑞典爱立信公司开发。它被广泛应用于构建高可靠性、分布式、可扩展的软件系统,尤其适合用于构建通信和实时系统。 这个RPM软件包是Erlang版本22.3的二进制安装程序。RPM是一种用于Linux发行版的软件包管理系统,它可以方便地安装、更新和卸载软件包。x86_64表示该软件包适用于64位的x86处理器架构。 要安装erlang-22.3-1.el7.x86_64.rpm,可以使用以下命令: ``` $ sudo yum install erlang-22.3-1.el7.x86_64.rpm ``` 该命令将自动解析并安装erlang软件包及其依赖项。安装完成后,您可以在系统上使用Erlang编程语言开发和运行应用程序。 Erlang的特点包括强大的并发性、容错机制和热代码升级功能。它通过基于消息传递的并发模型来实现高度并发和分布式计算。因此,它经常用于构建需要高可用性和实时性的应用,例如电信系统、金融交易系统和多人在线游戏等。 总结来说,erlang-22.3-1.el7.x86_64.rpm是Erlang编程语言版本22.3的RPM软件包,它为CentOS和RHEL操作系统提供了64位的安装程序,让用户可以方便地在这些系统上安装和使用Erlang编程语言。 ### 回答2: erlang-22.3-1.el7.x86_64.rpm 是一种用于Linux操作系统的RPM软件包,主要用于安装和管理Erlang编程语言的运行环境。 Erlang是一种面向并发和分布式应用的编程语言,它具有高可用性、容错性和可伸缩性。Erlang编译器将Erlang代码转换为字节码,并在Erlang虚拟机(BEAM)上运行。BEAM虚拟机负责执行字节码并管理并发和分布式运行环境。 erlang-22.3-1.el7.x86_64.rpm 是Erlang运行环境的一个版本,适用于64位的x86_64架构,并且兼容CentOS和Red Hat Enterprise Linux 7 (EL7)版本。.rpm是一种RPM软件包的扩展名,RPM是一种常用的软件包管理工具,它能够自动处理软件的安装、升级和卸载。 要安装 erlang-22.3-1.el7.x86_64.rpm 软件包,可以使用RPM软件包管理器进行操作。在终端中使用适当的命令,例如 "rpm -i erlang-22.3-1.el7.x86_64.rpm",即可将软件包安装到系统中。 安装完成后,系统就会拥有Erlang编程语言的运行环境,开发人员可以使用Erlang语言来编写并发和分布式应用程序。Erlang提供了丰富的库和工具,使开发过程更加高效和便捷。 总结来说,erlang-22.3-1.el7.x86_64.rpm 是一个Erlang编程语言的运行环境软件包,适用于64位的x86_64架构,可在CentOS和Red Hat Enterprise Linux 7上安装和使用。安装该软件包后,就可以使用Erlang来编写并发和分布式应用。 ### 回答3: erlang-22.3-1.el7.x86_64.rpm是指为CentOS 7操作系统提供的Erlang编程语言的软件包。Erlang是一种函数式编程语言,经过设计用于支持分布式、并发和容错系统。它由瑞典爱立信公司开发,并广泛应用于电信、金融和互联网行业。 这个软件包的版本是22.3,是指Erlang的主要版本。每个主要版本都带来了新功能、改进和修复旧版本的问题。这个版本是针对x86_64架构的,适用于64位的CentOS 7操作系统。 .rpm是一种Linux软件包管理器使用的包格式扩展名,用于安装、升级、配置和删除软件包。使用.rpm文件可以方便地在CentOS操作系统中安装、升级和管理Erlang软件。 通过安装这个rpm软件包,您可以在CentOS 7系统中使用Erlang编程语言开发和运行分布式和并发系统。Erlang提供了许多库和工具,使得开发复杂系统更加容易。它的并发模型和容错机制使得编写可靠的分布式应用程序变得更加简单。 总之,erlang-22.3-1.el7.x86_64.rpm是适用于CentOS 7系统的Erlang编程语言软件包。通过安装和使用这个软件包,您可以在CentOS 7上进行Erlang编程,并享受到Erlang在分布式、并发和容错方面的优势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值