当前位置:文档之家› 常用ARM v4指令集及汇编

常用ARM v4指令集及汇编

常用ARM v4指令集及汇编
常用ARM v4指令集及汇编

常用ARM v4指令集及汇编

前言

零零散散用了大概一周的时间,在《常用ARM指令集及汇编》(2003年12月1日)的基础上,大致学习了一遍ARM指令集和汇编,看的过程当中更正了一些错误的地方,并结合其它资料适当添加了一些内容,也做了一些删减,现分享出来,希望能帮助到需要的人。

文中必然还有一些错误还有待改进,有些地方还需要解释的更加详细,本人精力有限,希望有心的读者,订正并增加注释,最好也分享出来,以方便大家对ARM指令的深入理解。

作为刚入行的新手,不谦虚的推荐几本书:《ARM体系结构与编程-杜春雷》,《嵌入式系统体系结构、编程与设计-Raj Kamal著,贾建斌译》,《嵌入式系统:采用公开源代码和StrongARM_XScale处理器-毛德操》。这几本书到底好不好,看个人需求和喜好吧,仁者见仁智者见智。

最后,感谢《常用ARM指令集及汇编》的原作者和其它资料的作者让我有机会学习我不熟悉的东西,谢谢。

learllp

2015-11-09

目录

常用ARM v4指令集及汇编.......................................................................................... I 前言 ............................................................................................................................. I I 目录 ............................................................................................................................ I II ARM v4指令集及汇编.. (1)

一、ARM处理器寻址方式 (1)

寄存器寻址 (1)

立即寻址 (1)

寄存器偏移寻址 (2)

寄存器间接寻址 (2)

基址寻址 (3)

多寄存器寻址 (3)

堆栈寻址 (3)

块拷贝寻址 (4)

相对寻址 (4)

二、指令集介绍 (5)

ARM指令集 (5)

指令格式 (5)

基本格式 (5)

第2个操作数 (5)

1.#immed_8r常数表达式 (5)

2.Rm 寄存器方式 (6)

3.Rm,shift寄存器移位方式 (6)

条件码 (7)

ARM 存储器访问指令 (8)

◆LDR和STR (8)

◆LDM和STM (11)

◆SWP (14)

ARM 数据处理指令 (15)

数据传送指令 (15)

算术逻辑运算指令 (16)

ARM 跳转指令 (21)

ARM 协处理器指令 (22)

ARM 杂项指令 (24)

ARM 伪指令 (26)

Thumb 指令集 (29)

Thumb 指令集与ARM 指令集的区别 (29)

跳转指令 (29)

数据处理指令 (29)

单寄存器加载和存储指令 (29)

批量寄存器加载和存储指令 (30)

Thumb 存储器访问指令 (30)

伪指令 (31)

符号定义伪指令 (32)

数据定义伪指令 (34)

报告伪指令 (39)

汇编控制伪指令 (41)

杂项伪指令 (43)

◆AREA (45)

◆CODE16 和CODE32 (46)

◆END (46)

◆ENTRY (46)

◆EQU (47)

◆EXPORT 和GLOBAL (47)

◆IMPORT 和EXTERN (47)

◆GET 和INCLUDE (48)

◆INCBIN (48)

◆KEEP (49)

◆NOFP (49)

◆REQUIRE (49)

◆PEQUIRE8 和PRESERVE8 (49)

◆RN (49)

◆ROUT (50)

ARM 伪指令 (50)

◆ADR (50)

◆NOP (51)

◆LDFD (51)

◆LDFS (51)

三、ARM汇编程序设计 (51)

文件格式 (51)

ARM 汇编的一些规范 (52)

汇编语句格式 (52)

标号 (52)

基于PC 的标号 (53)

基于寄存器的标号 (53)

绝对地址 (53)

局部标号 (53)

符号 (54)

常量 (54)

数字常数 (54)

字符常量 (54)

布尔常量 (55)

段定义 (55)

宏定义及其作用 (55)

子程序的调用 (56)

数据比较跳转 (57)

循环 (57)

数据块复制 (57)

栈操作 (58)

特殊寄存器定义及应用 (58)

散转功能 (58)

查表操作 (58)

长跳转 (59)

对信号量的支持 (59)

伪指令使用 (59)

一个完整的例子 (59)

外围部件控制 (60)

四、C与汇编混合编程 (60)

内嵌汇编 (60)

内嵌汇编的指令用法 (62)

内嵌汇编器与armasm 汇编器的差异 (63)

内嵌汇编注意事项 (63)

访问全局变量 (65)

C与汇编相互调用 (65)

寄存器的使用规则 (66)

堆栈使用规则 (66)

参数传递规则 (66)

C程序调用汇编程序 (67)

调用汇编的C函数: (67)

汇编程序调用C程序 (68)

五、ARM 指令集列表 (69)

ARM 存储器访问指令表列表 (69)

ARM 数据处理指令列表 (70)

ARM 乘法指令列表 (71)

ARM 跳转指令列表 (72)

ARM 协处理器指令列表 (73)

ARM 杂项指令列表 (74)

ARM 伪指令列表 (75)

六、Thumb 指令集列表 (120)

Thumb 存储器访问指令列表 (120)

Thumb 数据处理指令列表 (121)

Thumb 跳转指令及软中断指令列表 (122)

Thumb 伪指令列表 (123)

七、汇编预定义变量及伪指令 (124)

预定义的寄存器和协处理器名 (124)

通用寄存器 (124)

程序状态寄存器 (124)

浮点数寄存器 (124)

协处理器及协处理器寄存器 (125)

八、内置变量列表 (125)

九、伪指令列表 (126)

十、指令条件码列表 (128)

十一、CPSR 和S PSR 分配图 (129)

ARM v4指令集及汇编

ARM 处理器是基于精简指令集计算机(RISC)原理设计的,指令集和相关译码机制较为简单,具有32 位ARM 指令集和16 位Thumb 指令集。ARM 指令集效率高,但是代码密度低,而Thumb 指令集具有更好的代码密度,却仍然保持ARM 的大多数性能上的优势,它是ARM 指令集的子集,主要用于编译器设计。所有ARM 指令都是可以有条件执行的,而Thumb 指令仅有一条指令具备条件执行功能。ARM 程序和Thumb 程序可相互调用,相互之间的状态切换开销几乎为零。

一、ARM处理器寻址方式

寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式,ARM 处理器有9 种基本寻址方式。

寄存器寻址

操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直接取出寄存器值操作。

寄存器寻址指令举例如下:

MOV R1,R2 ;R2 -> R1

SUB R0,R1,R2 ;R1 - R2->R0

立即寻址

立即寻址指令中的操作码字段后面的地址码部分就是操作数本身,也就是说,数据就包含在指令当中,取出指令也就取出了可以立即使用的操作数(立即数)。

立即寻址指令举例如下:

SUBS R0,R0,#1 ;R0–1 ->R0

MOV R0,#0xff00 ;0xff00 ->R0

立即数要以“#”为前缀,表示16 进制数值时以“0x”表示。

1

寄存器偏移寻址

寄存器偏移寻址是ARM 指令集特有的寻址方式,当第 2 操作数是寄存器偏移方式时,第2个寄存器操作数在与第1个操作数结合之前,选择进行移位操作。

寄存器偏移寻址方式指令举例如下:

MOV R0,R2,LSL #3 ;R2 的值左移3 位,结果放入R0,即R0 = R2 * 8

ANDS R1,R1,R2,LSL R3 ;R2 的值左移R3 位,然后和R1 相与操作,结果放入R1 可采用的移位操作如下:

LSL:逻辑左移(Logical Shift Left),寄存器中字的低端空出的位补0。

LSR:逻辑右移(Logical Shift Right),寄存器中字的高端空出的位补0。

ASR:算术右移(Arithmetic Shift Right),移位过程中保持符号位不变,即如果源操作数为正数,则字的高端空出的位补0,否则补1。

ROR:循环右移(Rotate Right),由字的低端移出的位填入字的高端空出的位。

RRX:带扩展的循环右移(Rotate Right extended by 1place),操作数右移一位,高端空出的位用原 C 标志值填充。

各移位操作如下图所示:

寄存器间接寻址

寄存器间接寻址指令中的地址码给出的是一个通用寄存器编号,所需要的操作数

2

保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针。

寄存器间接寻址指令举例如下:

LDR R1,[R2] ;将R2 中的数值作为地址,取出此地址中的数据保存在R1 中

SWP R1,R1,[R2];将如中的数值作为地址,取出此地址中的数值与R1 中的值交换

基址寻址

基址寻址是将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址,基址寻址用于访问基址附近的存储单元,常用于查表,数组操作,功能部件寄存器访问等。

基址寻址指令举例如下:

LDR R2,[R3,#0x0F] ;将R3中的数值加0x0F作为地址,将该地址保存在R2中

STR R1,[R0,#-2] ;将R0中的数值减2作为地址,把R1中的内容保存到此地址

多寄存器寻址

多寄存器寻址就是一次可以传送几个寄存器值,允许一条指令传送16 个寄存器的任何子集或所有寄存器。

多寄存器寻址指令举例如下:

LDMIA R1!,{R2-R7,R12} ;将[ R1] 单元中的数据读出到R2-R7,R12,R1自动加1

STMIA R0!,{R3-R6,R10} ;将R3-R6,R10中的数据保存到[R0],R0自动加1

使用多寄存器寻址指令时,寄存器子集的顺序由小到大的顺序排列,连续的寄存器可用“-”连接,否则用“,”分隔书写。

堆栈寻址

堆栈是特定顺序进行存取的存储区,操作顺序分为“后进先出”和“先进后出”,堆栈寻址是隐含的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈),指针所指向的存储单元就是堆栈的栈顶。存储器堆栈可分为两种:

向上生长:向高地址方向生长,称为递增堆栈。

向下生长:向低地址方向生长,称为递减堆栈。堆栈指针指向最后压入堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个要放入的空位置,称为空堆栈。这样就有4种类型的堆栈表示。

满递增:堆栈通过递增存储器的地址向上增长,堆栈指针指向堆栈内含有效数据项的最高地址。指令如LDMFA,STMFA 等。

空递增:堆栈通过递增存储器的地址向上增长,堆栈指针指向堆栈内的第一个空位置。指令如LDMEA,STMEA 等。

3

满递减:堆栈通过递减存储器的地址向下增长,堆栈指针指向堆栈内含有效数据项的最低地址。指令如LDMFD,STMFD 等。

空递减:堆栈通过递减存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置。指令如LDMED,STMED 等。堆栈寻址指令举例如下:

STMFD SP!,{R1-R7,LR} ;将R1~R7,LR 入栈

LDMFD SP!,{R1-R7,LR} ;数据出栈,放入R1~R7,LR 寄存器

块拷贝寻址

多寄存器传送指令用于一块数据从存储器的某一位置拷贝到另一位置。

块拷贝寻址指令举例如下:

STMIA R0!,{R1-R7} ;将R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之后增加,增长方向为向上增长

STMIB R0!,{R1-R7} ;将R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之前增加,增长方向为向上增长

STMDA R0!,{R1-R7} ;将R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之后增加,增长方向为向下增长

STMDB R0!,{R1-R7} ;将R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之前增加,增长方向为向下增长

相对寻址

相对寻址是基址寻址的一种变通,由程序计数器PC 提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。

相对寻址指令举例如下:

BL ROUTE1 ;调用ROUTE1 子程序

BEQ LOOP ;条件跳转到LOOP 标号处

LOOP MOV R2,#2

ROUTE1

4

5

二、指令集介绍 ARM 指令集

指令格式 基本格式

{}{S} {,} 其中,<>内的项是必须的,{}内的项是可选的,如是指令助记符,是必须的,而{}为指令执行条件,是可选的,如果不写则使用默认条件 AL(无条件执行)。

opcode 指令助记符,如 LDR ,STR 等 cond 执行条件,如 EQ ,NE 等

S 是否影响 CPSR 寄存器的值,带S 则影响 CPSR ,否则不影响 Rd 目标寄存器

Rn

第一个操作数的寄存器

operand2 第二个操作数

指令格式举例如下:

SUBNES R1,R1,#0xD ;条件执行减法运算(NE),R1-0xD=>R1,影响CPSR 寄存器,带有S

第2个操作数

在 ARM 指令中,灵活的使用第 2 个操作数能提高代码效率,第 2 个操作数形式如有3种形式:

1.#immed_8r 常数表达式

该常数必须对应 8 位位图,即常数是由一个 8 位的常数循环移位偶数位得到。此处immed_8r 可以是一个32位的立即数,但这不是一个任意的32位立即数,它必须是一个8位立即数在32位范围内进行偶数次循环右移能够获得的数,否则编译时

会出错。在12位的operand2中:后8位存数据,前4位存移位的次数。8位存数据:解释了“该常数必须对应8位位图”。4位存移位的次数:解释了为什么只能移偶数位。4位只有16种可能值,而32位数可以循环移位32次(32种可能),那就只好限制:只能移偶数位,一次移动两位,好像一个16位数在移位,16种移位可能。

合法常量:0x3FC、0、0xF0000000、200,0xF0000001

非法常量:0x1FE、511、0xFFFF、0x1010、0xF0000010

解释:

0x3FC,可以通过对0xFF循环右移30次获得。

0xF0000001,可以通过对0x1F循环右移4次获得。

0x1010,不能通过对某个8位数循环右移偶数次得到,所以非法。

常数表达式应用举例如下:

MOV R0,#1 ;R0=1

AND R1,R2,#0x0F ;R2 与0x0F,结果保存在R1

LDR R0,[R1],#-4 ;读取R1 地址上的存储器单元内容,且R1=R1-4

2.Rm 寄存器方式

在寄存器方式下操作数即为寄存器的数值。寄存器方式应用举例:

SUB R1,R1,R2 ;R1 =R1-R2

MOV PC,R0 ;PC=R0,程序跳转到指定地址

LDR R0,[R1],-R2 ;先读取[ R1] 的内容并存入R0,后R1=R1-R2

3.Rm,shift寄存器移位方式

将寄存器的移位结果作为操作数,但RM 值保存不变,移位方法如下:

ASR #n 算术右移n 位(1≤n≤32)

LSL #n 逻辑左移n 位(1≤n≤31)

LSR #n 逻辑左移n 位(1≤n≤32)

ROR #n 循环右移n 位(1≤n≤31)

RRX 带扩展的循环右移1 位

寄存器偏移方式应用举例:

ADD R1,R1,R1,LSL #3 ;R1=R1*9,此处Rs位置为一个立即数

SUB R1,R1,R2,LSR #2 ;R1=R1-R2*4

R15 为处理器的程序计数器PC,一般不要对其进行操作,而且有些指令是不允许使用R15,如UMULL 指令。

6

条件码

使用指令条件码,可实现高效的逻辑操作,提高代码效率。

条件码表

对于Thumb 指令集,只有 B 指令具有条件码执行功能,此指令条件码同上表,但如果为无条件执行时,条件码助记符“AL”不能在指令中书写。

条件码应用举例如下:

比较两个值大小,并进行相应加 1 处理,C 代码为

if(a>b)

a++;

else b++;

对应的ARM 指令如下。其中R0 为a,R1 为b。

CMP R0,R1 ;R0 与R1 比较

ADDHI R0,R0,#1 ;若R0>R1,则R0=R0+1

ADDLS R1,R1,#1 ;若R0<=R1,则R1=R1+1

若两个条件均成立,则将这两个数值相加,C 代码为

If((a!=10)&&(b!=20))

a=a+b;

对应的ARM 指令如下,其中R0为a,R1 为b。

CMP R0,#10 ;比较R0 是否为10

CMPNE R1,#20 ;若R0 不为10,则比较R1 是否20

ADDNE R0,R0,R1 ;若R0 不为10 且R1 不为20,指令执行,R0=R0+R1

7

ARM 存储器访问指令

ARM 处理是加载/存储体系结构的典型的RISC 处理器,对存储器的访问只能使用加载和存储指令实现。ARM 的加载/存储指令是可以实现字、半字、无符/有符字节操作;批量加载/存储指令可实现一条指令加载/存储多个寄存器的内容,大大提高效率;SWP 指令是一条寄存器和存储器内容交换的指令,可用于信号量操作等。ARM 处理器是冯.诺依曼或者哈佛存储结构,程序空间、RAM 空间及IO 映射空间统一编址,除对RAM 操作以外,对外围IO、程序数据的访问也均要通过加载/存储指令进行。

ARM 存储访问指令表

◆LDR和STR

单一加载/存储字和无符号字节指令。使用单一数据传送指令(STR和LDR)来装载和存储单一字节或字的数据从/到内存。LDR 指令用于从内存中读取数据放入寄存器中;STR 指令用于将寄存器中的数据保存到内存。指令格式如下:

LDR{cond}{T} Rd,<地址> ;加载指定地址上的数据(字),放入Rd 中STR{cond}{T} Rd,<地址> ;存储数据(字)到指定地址的存储单元,要存储的数据在Rd 中

LDR{cond}B{T} Rd,<地址> ;加载字节数据,放入Rd 中,即Rd 最低字节

8

有效,高24 位清零

STR{cond}B{T} Rd,<地址> ;存储字节数据,要存储的数据在Rd,最低字节有效

其中,T 为可选后缀,若指令有T,那么即使处理器是在特权模式下,存储系统也将访问看成是处理器是在用户模式下。T 在用户模式下无效,不能与前索引偏移一起使用T。LDR/STR 指令寻址是非常灵活的,由两部分组成,一部分为一个基址寄存器,可以为任一个通用寄存器,另一部分为一个地址偏移量。

地址偏移量有以下 3 种格式:

(1)立即数。立即数可以是一个无符号数值,这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值。指令举例如下:

LDR R1,[R0,#0x12] ;将R0+0x12 地址处的数据读出,保存到R1 中(R0 的值不变) LDR R1,[R0,#-0x12] ;将R0-0x12 地址处的数据读出,保存到R1 中(R0 的值不变) LDR R1,[R0] ;将R0 地址处的数据读出,保存到R1 中(零偏移)

(2)寄存器。寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。指令举例如下:

LDR R1,[R0,R2] ;将R0+R2 地址的数据计读出,保存到R1 中(R0 的值不变)

LDR R1,[R0,-R2] ;将R0-R2 地址处的数据计读出,保存到R1 中(R0 的值不变)

(3)寄存器及移位常数。寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。指令举例如下:

LDR R1,[R0,R2,LSL #2] ;将R0+R2*4 地址处的数据读出,保存到R1 中(R0,R2 的值不变)

LDR R1,[R0,-R2,LSL #2];将R0-R2*4 地址处的数据计读出,保存到R1 中(R0,R2 的值不变)

从寻址方式的地址计算方法划分,加载/存储指令有以下4 种形式:

(1)零偏移。Rn 的值作为传送数据的地址,即地址偏移量为0。指令举例如下:

LDR Rd,[Rn]

(2)前索引偏移。在数据传送之前,将偏移量加到Rn 中,其结果作为传送数据的存储地址。若使用后缀“!”,则结果写回到Rn 中,且Rn 值不允许为R15。指令举例如下:

LDR Rd,[Rn,#0x04]!

LDR Rd,[Rn,#-0x04]

(3)程序相对偏移。程序相对偏移是索引形式的另一个版本。汇编器根据PC 寄存器计算偏移量,并将PC 寄存器作为Rn 生成前索引指令。不能使用后缀“!”。指令举例如下:

LDR Rd,label ;label 为程序标号,label 必须是在当前指令的±4KB范围内

(4)后索引偏移。Rn 的值用做传送数据的存储地址。在数据传送后,将偏移量与Rn相加,结果写回到Rn 中。Rn 不允许是R15。指令举例如下:

LDR Rd,[Rn],#0x04

9

大多数情况下,必须保证用于32位传送的地址是32位对齐的。(所谓对齐,通常理解就是变量存储的首地址要能够整除变量的字节数,这样有助于CPU高效率的读取数据。对于C语言,结构体本身按照结构体成员中最大的变量类型所占的字节数对齐,比如,变量中有8位的long long 型成员,最终,结构体就按照8位对齐。例,//AMD 32位CPU,DEV-C++ 5.4.0编译器,XP2系统

struct test

{

char x1[9];//占10个字节

short x2;//占2个字节

char x3[13];//占20个字节

double x4;//占8个字节

char x5[5];//占8个字节,为了结构体对齐

};//结构体共占48个字节

各变量起始地址分别为:0x22fea8,0x22feb2,0x22feb4,0x22fec8,0x22fed0 )加载/存储字和无符号字节指令举例如下:

LDR R2,[R5] ;加载R5 指定地址上的数据(字),放入R2 中

STR R1,[R0,#0x04] ;将R1 的数据存储到R0+0x04 存储单元,R0 值不变

LDRB R3,[R2],#1 ;读取R2地址上的一个字节的数据,并保存到R3中,R2=R3+1

STRB R6,[R7] ;读R6的数据保存到R7指定的地址中,只存储一个字节

加载/存储半字和带符号字节。这类LDR/STR 指令可能加载带符字节\加载带符号半字、加载/存储无符号半字。偏移量格式、寻址方式与加载/存储字和无符号字节指令相同。指令格式如下:

LDR{cond}SB Rd,<地址> ;加载指定地址上的数据(带符号字节),放入Rd 中

LDR{cond}SH Rd,<地址> ;加载指定地址上的数据(带符号半字),放入Rd 中

LDR{cond}H Rd,<地址> ;加载半字数据,放入Rd中,低16位有效,高16位清零

STR{cond}H Rd,<地址> ;存储半字数据,要存储的数据在Rd,低16 位有效

说明:带符号位半字/字节加载是指带符号位加载扩展到32 位;无符号位半字加载是指零扩展到32 位。

地址对齐,对半字传送的地址必须为偶数。非半字对齐的半字加载将使Rd 内容不可靠,非半字对齐的半字存储将使指定地址的2字节存储内容不可靠。

加载/存储半字和带符号字节指令举例如下:

LDRSB R1 [R0,R3] ;将[R0+R3]上的字节数据读出到R1,高24位用符号位扩展

LDRSH R1,[R9] ;将R9地址上的半字数据读出到R1,高16位用符号位扩展

LDRH R6,[R2],#2 ;将R2地址上的半字数据读出到R6,高16位用零扩展,R2=R2+1 SHRH R1,[R0,#2]! ;将R1的数据保存到[R0+2],只存储低2字节数据,R0=R0+2

LDR/STR 指令用于对内存变量的访问,内存缓冲区数据的访问、查表、外围部件的控制操作等等,若使用LDR 指令加载数据到PC寄存器,则实现程序跳转功能,这样也就实现了程序散转。

10

NumCount EQU 0x40003000 ;定义变量NumCount

GPIO 设置

LDR R0,=NumCount ;使用LDR 伪指令装载NumCount的地址到R0

LDR R1,[R0] ;取出变量值

ADD R1,R1,#1 ;NumCount=NumCount+1

STR R1,[R0] ;保存变量值

GPIO-BASE EQU 0Xe0028000 ;定义GPIO寄存器的基地址

LDR R0,=GPIO-BASE

LDR R1,=0x00FFFF00 ;装载32位立即数,即设置值

STR R1,[R0,#0x0C] ;IODIR=0x00FFFF00,IODIR 的地址为0xE002800C

MOV R1,#0x00F00000

STR R1,[R0,#0x04] ;IOSET=0x00F00000,IOSET 的地址为0xE0028004

程序散转

MOV R2,R2,LSL #2 ;功能号乘上4,以便查表

LDR PC,[PC,R2] ;查表取得对应功能子程序地址,并跳转

NOP

FUN-TAB DCD FUN-SUB0

DCD FUN-SUB1

DCD FUN-SUB2

◆LDM和STM

批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。LDM为加载多个寄存器,STM为存储多个寄存器。允许一条指令传送16个寄存器的任何子集或所有寄存器。指令格式如下:

LDM{cond}<模式> Rn{!},reglist{^}

STM{cond}<模式> Rn{!},reglist{^}

LDM /STM 的主要用途是现场保护、数据复制、参数传送等。其模式有8种,如下:(前面4种用于数据块的传输,后面 4 种是堆栈操作)

(1) IA:每次传送后地址加4

(2) IB:每次传送前地址加4

(3) DA:每次传送后地址减4

(4) DB:每次传送前地址减4

(5) FD:满递减堆栈

11

(6) ED:空递增堆栈

(7) FA:满递增堆栈

(8) EA:空递增堆栈

其中,寄存器Rn 为基址寄存器,装有传送数据的初始地址,Rn 不允许为R15;后缀“!”表示最后的地址写回到Rn中;寄存器列表reglist 可包含多于一个寄存器或寄存器范围,使用“,”分开,如{R1,R2,R6-R9},寄存器排列由小到大排列;“^”后缀不允许在用户模式和系统模式下使用,若在LDM指令用寄存器列表中包含有PC 时使用,那么除了正常的多寄存器传送外,将SPSR拷贝到CPSR中,这可用于异常处理返回;使用“^”后缀进行数据传送且寄存器列表不包含PC 时,加载/存储的是用户模式的寄存器,而不是当前模式的寄存器。

地址对准――这些指令忽略地址的位[1:0] 批量加载/存储指令举例如下:

LDMIA R0!,{R3-R9} ;加载R0 指向的地址上的多字数据,保存到R3~R9 中,R0 值更新

STMIA R1!,{R3-R9} ;将R3~R9 的数据存储到R1指向的地址上,R1值更新

STMFD SP!,{R0-R7,LR} ;现场保存,将R0~R7、LR 入栈

LDMFD SP!,{R0-R7,PC} ;恢复现场,异常处理返回

在进行数据复制时,先设置好源数据指针,然后使用块拷贝寻址指令LDMIA/STMIA、LDMIB/STMIB、LDMDA/STMDA、LDMDB/STMDB 进行读取和存储。而进行堆栈操作时,则要先设置堆栈指针,一般使用SP 然后使用堆栈寻址指令STMFD/LDMFD、STMED。LDMED、STMFA/LDMFA、STMEA/LDMEA 实现堆栈操作。

多寄存器传送指令示意图如下图所示,其中R1为指令执行前的基址寄存器,R1则为指令执行完后的基址寄存器。

a)指令STMIA R1!,

{R5-R7}

12

c)指令STMDA R1!,

{R5-R7}

d)指令STMDB R1!,

数据是存储在基址寄存器的地址之上还是之下,地址是在存储第一个值之前还是之后增加还是减少。

多寄存器传送指令映射

13

LDR R0,=SrcData ;设置源数据地址

LDR R1,=DstData ;设置目标地址

LDMIA R0,{R2-R9} ;加载8 字数据到寄存器R2-R9

TMIA R1,{R2~R9} ;存储寄存器R2~R9 到目标地址

使用LDM/STM 进行现场寄存器保护,常在子程序中或异常处理使用:

SENDBYTE

STMFD SP!,{R0-R7,LR} ;寄存器入堆

BL DELAY ;调用DELAY子程序

LDMFD SP!,{R0-R7,PC} ;恢复寄存器,并返回

◆SWP

寄存器和存储器交换指令。SWP 指令用于将一个内存单元(该单元地址放在寄存器Rn 中)的内容读取到一个寄存器Rd 中,同时将另一个寄存器Rm 的内容写入到该内存单元中。使用SWP可实现信号量操作。

指令格式如下:SWP{cond}{B} Rd,Rm,[Rn]

其中,B 为可选后缀,若有B,则交换字节,否则交换32 位字:Rd 为数据从存储器加载到的寄存器;Rm 的数据用于存储到存储器中,若Rd 与Rm 相同,则为寄存器与存储器内容进行交换;Rn 为要进行数据交换的存储器地址,Rn 不能与Rd 和Rm 相同。

SWP 指令举例如下:

SWP R1,R1,[R0] ;将R1的内容与R0指向的存储单元的内容进行交换

SWPB R1,R2,[R0] ;将R0指向的存储单元内容读取一字节数据到R1中

;(高24 位清零),并将R2的内容写入到该内存单元中

;(最低字节有效)

使用SWP 指令可以方便地进行信号量的操作:

12C_SEM EQU 0x40003000

12C_SEM_WAIT

MOV R0,#0

LDR R0,=12C_SEM

SWP R1,R1,[R0] ;取出信号量,并设置其为0

CMP R1,#0 ;判断是否有信号

BEQ 12C_SEM_WAIT ;若没有信号,则等待

14

(完整word版)汇编语言常用指令大全,推荐文档

MOV指令为双操作数指令,两个操作数中必须有一个是寄存器. MOV DST , SRC // Byte / Word 执行操作: dst = src 1.目的数可以是通用寄存器, 存储单元和段寄存器(但不允许用CS段寄存器). 2.立即数不能直接送段寄存器 3.不允许在两个存储单元直接传送数据 4.不允许在两个段寄存器间直接传送信息 PUSH入栈指令及POP出栈指令: 堆栈操作是以“后进先出”的方式进行数据操作. PUSH SRC //Word 入栈的操作数除不允许用立即数外,可以为通用寄存器,段寄存器(全部)和存储器. 入栈时高位字节先入栈,低位字节后入栈. POP DST //Word 出栈操作数除不允许用立即数和CS段寄存器外, 可以为通用寄存器,段寄存器和存储器. 执行POP SS指令后,堆栈区在存储区的位置要改变. 执行POP SP 指令后,栈顶的位置要改变. XCHG(eXCHanG)交换指令: 将两操作数值交换. XCHG OPR1, OPR2 //Byte/Word 执行操作: Tmp=OPR1 OPR1=OPR2 OPR2=Tmp 1.必须有一个操作数是在寄存器中 2.不能与段寄存器交换数据 3.存储器与存储器之间不能交换数据. XLAT(TRANSLATE)换码指令: 把一种代码转换为另一种代码. XLAT (OPR 可选) //Byte 执行操作: AL=(BX+AL) 指令执行时只使用预先已存入BX中的表格首地址,执行后,AL中内容则是所要转换的代码. LEA(Load Effective Address) 有效地址传送寄存器指令 LEA REG , SRC //指令把源操作数SRC的有效地址送到指定的寄存器中. 执行操作: REG = EAsrc 注: SRC只能是各种寻址方式的存储器操作数,REG只能是16位寄存器 MOV BX , OFFSET OPER_ONE 等价于LEA BX , OPER_ONE MOV SP , [BX] //将BX间接寻址的相继的二个存储单元的内容送入SP中 LEA SP , [BX] //将BX的内容作为存储器有效地址送入SP中 LDS(Load DS with pointer)指针送寄存器和DS指令 LDS REG , SRC //常指定SI寄存器。 执行操作: REG=(SRC), DS=(SRC+2) //将SRC指出的前二个存储单元的内容送入指令中指定的寄存器中,后二个存储单元送入DS段寄存器中。

汇编语言入门

汇编语言入门教程 对初学者而言,汇编的许多命令太复杂,往往学习很长时间也写不出一个漂漂亮亮的程序,以致妨碍了我们学习汇编的兴趣,不少人就此放弃。所以我个人看法学汇编,不一定要写程序,写程序确实不是汇编的强项,大家不妨玩玩DEBUG,有时CRACK出一个小软件比完成一个程序更有成就感(就像学电脑先玩游戏一样)。某些高深的指令事实上只对有经验的汇编程序员有用,对我们而言,太过高深了。为了使学习汇编语言有个好的开始,你必须要先排除那些华丽复杂的命令,将注意力集中在最重要的几个指令上(CMP LOOP MOV JNZ……)。但是想在啰里吧嗦的教科书中完成上述目标,谈何容易,所以本人整理了这篇超浓缩(用WINZIP、WINRAR…依次压迫,嘿嘿!)教程。大言不惭的说,看通本文,你完全可以“不经意”间在前辈或是后生卖弄一下DEBUG,很有成就感的,试试看!那么――这个接下来呢?――Here we go!(阅读时看不懂不要紧,下文必有分解) 因为汇编是通过CPU和内存跟硬件对话的,所以我们不得不先了解一下CPU和内存:(关于数的进制问题在此不提) CPU是可以执行电脑所有算术╱逻辑运算与基本I/O 控制功能的一块芯片。一种汇编语言只能用于特定的CPU。也就是说,不同的CPU其汇编语言的指令语法亦不相同。个人电脑由1981年推出至今,其CPU发展过程为:8086→80286→80386→80486→PENTIUM →……,还有AMD、CYRIX等旁支。后面兼容前面CPU的功能,只不过多了些指令(如多能奔腾的MMX指令集)、增大了寄存器(如386的32位EAX)、增多了寄存器(如486的FS)。为确保汇编程序可以适用于各种机型,所以推荐使用8086汇编语言,其兼容性最佳。本文所提均为8086汇编语言。寄存器(Register)是CPU内部的元件,所以在寄存器之间的数据传送非常快。用途:1.可将寄存器内的数据执行算术及逻辑运算。2.存于寄存器内的地址可用来指向内存的某个位置,即寻址。3.可以用来读写数据到电脑的周边设备。8086 有8个8位数据寄存器,这些8位寄存器可分别组成16位寄存器:AH&AL=AX:累加寄存器,常用于运算;BH&BL=BX:基址寄存器,常用于地址索引;CH&CL=CX:计数寄存器,常用于计数;DH&DL=DX:数据寄存器,常用于数据传递。为了运用所有的内存空间,8086设定了四个段寄存器,专门用来保存段地址:CS(Code Segment):代码段寄存器;DS(Data Segment):数据段寄存器;SS(Stack Segment):堆栈段寄存器;ES(Extra Segment):附加段寄存器。当一个程序要执行时,就要决定程序代码、数据和堆栈各要用到内存的哪些位置,通过设定段寄存器CS,DS,SS 来指向这些起始位置。通常是将DS固定,而根据需要修改CS。所以,程序可以在可寻址空间小于64K的情况下被写成任意大小。所以,程序和其数据组合起来的大小,限制在DS 所指的64K内,这就是COM文件不得大于64K的原因。8086以内存做为战场,用寄存器做为军事基地,以加速工作。除了前面所提的寄存器外,还有一些特殊功能的寄存器:IP(Intruction Pointer):指令指针寄存器,与CS配合使用,可跟踪程序的执行过程;SP(Stack Pointer):堆栈指针,与SS配合使用,可指向目前的堆栈位置。BP(Base Pointer):基址指针寄存器,可用作SS 的一个相对基址位置;SI(Source Index):源变址寄存器可用来存放相对于DS段之源变址指针;DI(Destination Index):目的变址寄存器,可用来存放相对于ES 段之目的变址指针。还有一个标志寄存器FR(Flag Register),有九个有意义的标志,将在下文用到时详细说明。 内存是电脑运作中的关键部分,也是电脑在工作中储存信息的地方。内存组织有许多可存放

(完整word版)汇编语言指令集合-吐血整理,推荐文档

8086/8088指令系统记忆表 数据寄存器分为: AH&AL=AX(accumulator):累加寄存器,常用于运算;在乘除等指令中指定用来存放操作数,另外,所有的I/O指令都使用这一寄存器与外界设备传送数据. BH&BL=BX(base):基址寄存器,常用于地址索引; CH&CL=CX(count):计数寄存器,常用于计数;常用于保存计算值,如在移位指令,循环(loop)和串处理指令中用作隐含的计数器. DH&DL=DX(data):数据寄存器,常用于数据传递。他们的特点是,这4个16位的寄存器可以分为高8位: AH, BH, CH, DH.以及低八位:AL,BL,CL,DL。这2组8位寄存器可以分别寻址,并单独使用。 另一组是指针寄存器和变址寄存器,包括: SP(Stack Pointer):堆栈指针,与SS配合使用,可指向目前的堆栈位置; BP(Base Pointer):基址指针寄存器,可用作SS的一个相对基址位置; SI(Source Index):源变址寄存器可用来存放相对于DS段之源变址指针; DI(Destination Index):目的变址寄存器,可用来存放相对于ES 段之目的变址指针。 指令指针IP(Instruction Pointer) 标志寄存器FR(Flag Register) OF(overflow flag) DF(direction flag) CF(carrier flag) PF(parity flag) AF(auxiliary flag) ZF(zero flag) SF(sign flag) IF(interrupt flag) TF(trap flag) 段寄存器(Segment Register) 为了运用所有的内存空间,8086设定了四个段寄存器,专门用来保存段地址: CS(Code Segment):代码段寄存器; DS(Data Segment):数据段寄存器; SS(Stack Segment):堆栈段寄存器;

PowerPC总汇编指令集

PowerPC汇编指令集 标签:汇编指令PowerPC PPC 2008-05-04 21:25 PowerPC 体系结构规范(PowerPC Architecture Specification)发布 于 1993 年,它是一个 64 位规范 ( 也包含 32 位子集 )。几乎所有常规可用 的 PowerPC(除了新型号 IBM RS/6000 和所有 IBM pSeries 高端服务器)都 是 32 位的。 PowerPC 处理器有 32 个(32 位或 64 位)GPR(通用寄存器)以及诸如 PC (程序计数器,也称为IAR/指令地址寄存器或 NIP/下一指令指针)、LR(链接寄存器)、CR(条件寄存器)等各种其它寄存器。有些 PowerPC CPU 还 有 32 个 64 位 FPR(浮点寄存器)。MPC555使用的PowerPC CPU是带有FPR 的。一些常用寄存器介绍如下: 通用寄存器的用途: r0在函数开始(function prologs)时使用。 r1堆栈指针,相当于ia32架构中的esp寄存器,idapro把这个寄存器反汇编标识为sp。 r2内容表(toc)指针,idapro把这个寄存器反汇编标识为rtoc。系统调用时,它包含系统调用号(这个好像跟系统有关吧)。 r3作为第一个参数和返回值。 r4-r10函数或系统调用开始的参数。 r11用在指针的调用和当作一些语言的环境指针。 r12它用在异常处理和glink(动态连接器)代码。 r13保留作为系统线程ID。 r14-r31 作为本地变量,非易失性。 专用寄存器的用途: lr链接寄存器,它用来存放函数调用结束处的返回地址。 ctr计数寄存器,它用来当作循环计数器,会随特定转移操作而递减。 xer定点异常寄存器,存放整数运算操作的进位以及溢出信息。 msr机器状态寄存器,用来配置微处理器的设定。 cr条件寄存器,它分成8个4位字段,cr0-cr7,它反映了某个算法操作的结果并且提供条件分支的机制。 寄存器r1、r14-r31是非易失性的,这意味着它们的值在函数调用过程保持不变。寄存器r2也算非易失性,但是只有在调用函数在调用后必须恢复它的值时才被处理。

x86汇编指令集

x86汇编指令集 数据传输指令它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据. 1. 通用数据传送指令. MOV 传送字或字节. MOVSX 先符号扩展,再传送. MOVZX 先零扩展,再传送. MOVSX reg16,r/m8 ; o16 0F BE /r [386] MOVSX reg32,r/m8 ; o32 0F BE /r [386] MOVSX reg32,r/m16 ; o32 0F BF /r [386] MOVZX reg16,r/m8 ; o16 0F B6 /r [386] MOVZX reg32,r/m8 ; o32 0F B6 /r [386] MOVZX reg32,r/m16 ; o32 0F B7 /r [386] PUSH 把字压入堆栈. POP 把字弹出堆栈. PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈. POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.

PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈. POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈. BSWAP 交换32位寄存器里字节的顺序 XCHG 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数) CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX ) XADD 先交换再累加.( 结果在第一个操作数里) XLAT 字节查表转换. ── BX 指向一张256 字节的表的起点, AL 为表的索引值(0-255,即 0-FFH); 返回AL 为查表结果. ( [BX+AL]->AL ) 2. 输入输出端口传送指令. IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} ) OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器) 输入输出端口由立即方式指定时, 其范围是0-255; 由寄存器DX 指定时, 其范围是0-65535. 3. 目的地址传送指令. LEA 装入有效地址. 例: LEA DX,string ;把偏移地址存到DX. LDS 传送目标指针,把指针内容装入DS. 例: LDS SI,string ;把段地址:偏移地址存到DS:SI. LES 传送目标指针,把指针内容装入ES. 例: LES DI,string ;把段地址:偏移地址存到ES:DI. LFS 传送目标指针,把指针内容装入FS.

51单片机汇编指令集(附记忆方法)

51单片机汇编指令集 一、数据传送类指令(7种助记符) MOV(英文为Move):对内部数据寄存器RAM和特殊功能寄存器SFR的数据进行传送; MOVC(Move Code)读取程序存储器数据表格的数据传送; MOVX (Move External RAM) 对外部RAM的数据传送; XCH (Exchange) 字节交换; XCHD (Exchange low-order Digit) 低半字节交换; PUSH (Push onto Stack) 入栈; POP (Pop from Stack) 出栈; 二、算术运算类指令(8种助记符) ADD(Addition) 加法; ADDC(Add with Carry) 带进位加法; SUBB(Subtract with Borrow) 带借位减法; DA(Decimal Adjust) 十进制调整; INC(Increment) 加1; DEC(Decrement) 减1; MUL(Multiplication、Multiply) 乘法; DIV(Division、Divide) 除法; 三、逻辑运算类指令(10种助记符) ANL(AND Logic) 逻辑与; ORL(OR Logic) 逻辑或; XRL(Exclusive-OR Logic) 逻辑异或; CLR(Clear) 清零; CPL(Complement) 取反; RL(Rotate left) 循环左移; RLC(Rotate Left throught the Carry flag) 带进位循环左移; RR(Rotate Right) 循环右移; RRC (Rotate Right throught the Carry flag) 带进位循环右移; SWAP (Swap) 低4位与高4位交换; 四、控制转移类指令(17种助记符) ACALL(Absolute subroutine Call)子程序绝对调用; LCALL(Long subroutine Call)子程序长调用; RET(Return from subroutine)子程序返回; RETI(Return from Interruption)中断返回; SJMP(Short Jump)短转移; AJMP(Absolute Jump)绝对转移; LJMP(Long Jump)长转移; CJNE (Compare Jump if Not Equal)比较不相等则转移;

ARM汇编指令集

ARM汇编指令集 1 跳转指令 1.1 跳转指令B: B LABLE ;跳转到标号LABEL处 B 0X1111 ;跳转到绝对地址0X1111处 1.2 带连接的跳转指令BL: START … BL NEXT ;跳转到标号NEXT处,同时保存当前PC到R14中 …;返回地址 … NEXT…;子程序入口 MOV PC,R14 ;返回 1.3 带状态切换的跳转指令BX: MOV R0, #0X0201 BX R0 ;程序跳转到0x0200处,微处理器切换到Thumb 状态(地址必须是4的倍数,否则产生不可预知的后果) 2算术运算指令 2.1不带进位加法指令ADD

ADD R0, R1, R2 ;R0←(R1)+(R2) ADD R0, R1, #112 ;R0←(R1)+ 112 ADD R0, R1, R2, LSL #1 ;R0←(R1)+(R2<<1) ;将R2中的值左移1位,再与R1值相加,结果送R0 2.2带进位加法指令ADC ADDS R0, R3, R6 ;加最低位字节,不带进位 ADCS R1, R4, R7 ;加第二个字,带进位 ADCS R2, R5,R8 ;加第三个字,带进位 ;三句话实现了96bit加法运算,由于ARM寄存器宽度只有32bit所以分三次相加 2.3 不带进位减法指令SUB ;S—进位标志 SUB R0, R1, R2 ;R0←(R1)- (R2) SUB R0, R1, #112 ;R0←(R1)- 112 SUB R0, R1 ,R2 LSL#1 ;R0←(R1)- (R2<<1) 2.4 带进位减法指令SBC SUBS R0, R3, R6 ;减最低位字节,不带进位 SBCS R1, R4, R7 ;减第二个字,带进位 SBCS R2, R5, R8 ;减第三个字,带进位 ;三句话实现了96bit减法运算,由于ARM寄存器宽度只有32bit所以分三次相减

STM 常用汇编指令

在嵌入式开发中,汇编程序常常用于非常关键的地方,比如系统启动时初始化,进出中断时的环境保护,恢复等对性能有要求的地方。 ARM指令集可以分为六大类,分别为数据处理指令、Load/Store指令、跳转指令、程序状态寄存器处理指令、协处理器指令和异常产生指令。 ARM指令使用的基本格式如下: 〈opcode〉{〈cond〉}{S}〈Rd〉,〈Rn〉{,〈operand2〉} opcode操作码;指令助记符,如LDR、STR等。 cond可选的条件码;执行条件,如EQ、NE等。 S可选后缀;若指定“S”,则根据指令执行结果更新CPSR中的条件码。 Rd目标寄存器。 Rn存放第1操作数的寄存器。 operand2第2个操作数 arm的寻址方式如下: 立即寻址 寄存器寻址 寄存器间接寻址 基址加偏址寻址 堆栈寻址 块拷贝寻址 相对寻址 这里不作详细描述,可以查阅相关文档。 数据处理指令 Load/Store指令 程序状态寄存器与通用寄存器之间的传送指令 转移指令 异常中断指令 协处理器指令 在S3C2410、S3C2440的数据手册中对各种汇编指令有详细的描述;这里只对较常见的作写介绍。 1、相对跳转指令:b、bl 这两条指令的不同之处在于bl指令除了跳转之外,还将返回地址(bl的下一条指令的地址)保存在lr寄存器中。 这两条指令的可跳转范围是当前指令前后32M。 b funa .... funa: b funb ....

funb: .... 2、数据传送指令mov,地址读取伪指令ldr mov指令可以把一个寄存器的值赋给另外一个寄存器,或者把一个常数赋给寄存器。 mov r1,r2 mov r1,#1024 mov传送的常数必须能用立即数来表示。当不能用立即数表示时,可以用ldr命令来赋值。ldr是伪命令,不是真实存在的指令,编译器会把它扩展成真正的指令;如果该常数能用“立即数”来表示,则使用mov指令,否则编译时将该常数保存在某个位置,使用内存读取指令把它读出来。 ldr r1,=1024 3、内存访问指令ldr、str、ldm、stm ldr既可以指低至读取伪指令,也可以是内存访问指令。当他的第二个参数前面有'='时标伪指令,否则表内存访问指令。 ldr指令从内存中读取数据到寄存器,str指令把寄存器的指存储到内存中,他们的操作数都是32位的。 ldr r1,[r2,#4] ldr r1,[r2] ldr r1,[r2],#4 str r1,[r2,#4] str r1,[r2] str r1,[r2],#4 寄存器传送指令可以用一条指令将16个可见寄存器(R0~R15)的任意子集合(或全部)存储到存储器或从存储器中读取数据到该寄存器集合中。与单寄存器存取指令相比,多寄存器数据存取可用的寻址模式更加有限。多寄存器存取指令的汇编格式如下: LDM/STM{}Rn{!}, 4、加减指令add、sub add r1,r2,#1 sub r1,r2,#1 5、程序状态寄存器的访问指令msr,mrs ARM指令中有两条指令,用于在状态寄存器和通用寄存器之间传送数据。修改状态寄存器一般是通过“读取-修改-写回”三个步骤的操作来实现的。这两条指令分别是: 状态寄存器到通用寄存器的传送指令(MRS) 通用寄存器到状态寄存器的传送指令(MSR) 其汇编格式如下: MRS{}Rd,CPSR|SPSR 其汇编格式如下:

汇编语言指令集

汇编语言指令集 一、数据传输指令 1. 通用数据传送指令. MOV(MOVe) 传送字或字节. MOVS(MOVe String) 串传送指令 MOVSX先符号扩展,再传送. MOVZX先零扩展,再传送. PUSH把字压入堆栈. POP把字弹出堆栈. PUSHA把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈. POPA把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈. PUSHAD把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈. POPAD把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈. BSWAP 交换32位寄存器里字节的顺序 XCHG (eXCHanG)交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数) CMPXCHG比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX ) XADD先交换再累加.( 结果在第一个操作数里) XLAT(TRANSLATE) 字节查表转换. ── BX 指向一张256 字节的表的起点, AL 为表的索引值(0-255,即0-FFH); 返回AL 为查表结果. ( [BX+AL]->AL ) 2. 输入输出端口传送指令. IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} ) OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器) 输入输出端口由立即方式指定时, 其范围是0-255; 由寄存器DX 指定时,其范围是0-65535. 3. 目的地址传送指令. LEA (Load Effective Address)装入有效地址. 例: LEA DX,string ;把偏移地址存到DX. LDS (Load DS with pointer)传送目标指针,把指针内容装入DS. 例: LDS SI,string ;把段地址:偏移地址存到DS:SI. LES (Load ES with pointer)传送目标指针,把指针内容装入ES. 例: LES DI,string ;把段地址:偏移地址存到ES:DI. LFS 传送目标指针,把指针内容装入FS. 例: LFS DI,string ;把段地址:偏移地址存到FS:DI. LGS 传送目标指针,把指针内容装入GS. 例: LGS DI,string ;把段地址:偏移地址存到GS:DI. LSS 传送目标指针,把指针内容装入SS. 例: LSS DI,string ;把段地址:偏移地址存到SS:DI. 4. 标志传送指令. LAHF (Load AH with Flags)标志寄存器传送,把标志装入AH. SAHF (Store AH into Flgs)标志寄存器传送,把AH内容装入标志寄存器. PUSHF (PUSH the Flags)标志入栈. POPF (POP the Flags)标志出栈.

一些常用的汇编语言指令

汇编语言常用指令 大家在做免杀或者破解软件的时候经常要用到汇编指令,本人整理出了常用的 希望对大家有帮助! 数据传送指令 MOV:寄存器之间传送注意,源和目的不能同时是段寄存器;代码段寄存器CS不能作为目的;指令指针IP不能作为源和目的。立即数不能直接传送段寄存器。源和目的操作数类型要一致;除了串操作指令外,源和目的不能同时是存储器操作数。 XCHG交换指令:操作数可以是通用寄存器和存储单元,但不包括段寄存器,也不能同时是存储单元,还不能有立即数。 LEA 16位寄存器存储器操作数传送有效地址指令:必须是一个16位寄存器和存储器操作数。 LDS 16位寄存器存储器操作数传送存储器操作数32位地址,它的16位偏移地址送16位寄存器,16位段基值送入DS中。 LES :同上,只是16位段基址送ES中。 堆栈操作指令 PUSH 操作数,操作数不能使用立即数, POP 操作数,操作数不能是CS和立即数 标志操作指令 LAHF:把标志寄存器低8位,符号SF,零ZF,辅助进位AF,奇偶PF,进位CF传送到AH 指定的位。不影响标志位。 SAHF:与上相反,把AH中的标志位传送回标志寄存器。 PUSHF:把标志寄存器内容压入栈顶。 POPF:把栈顶的一个字节传送到标志寄存器中。 CLC:进位位清零。 STC:进位位为1。 CMC:进位位取反。 CLD:使方向标志DF为零,在执行串操作中,使地址按递增方式变化。 STD:DF为1。 CLI:清中断允许标志IF。Cpu不相应来自外部装置的可屏蔽中断。 STI:IF为1。 加减运算指令

注意:对于此类运算只有通用寄存器和存储单元可以存放运算结果。如果参与运算的操作数有两个,最多只能有一个存储器操作数并且它们的类型必须一致。 ADD。 ADC:把进位CF中的数值加上去。 INC:加1指令 SUB。 SBB:把进位CF中数值减去。 DEC:减1指令。 NEG 操作数:取补指令,即用0减去操作数再送回操作数。 CMP:比较指令,完成操作数1减去操作数2,结果不送操作数1,但影响标志位。可根据ZF(零)是否被置1判断相等;如果两者是无符号数,可根据CF判断大小;如果两者是有符号数,要根据SF和OF判断大小。 乘除运算指令 MUL 操作数:无符号数乘法指令。操作数不能是立即数。操作数是字节与AL中的无符号数相乘,16位结果送AX中。若字节,则与AX乘,结果高16送DX,低16送AX。如乘积高半部分不为零,则CF、OF为1,否则为0。所以CF和OF表示AH或DX中含有结果的有效数。IMUL 操作数:有符号数乘法指令。基本与MUL相同。 DIV 操作数:被除数是在AX(除数8位)或者DX和AX(除数16位),操作数不能是立即数。如果除数是0,或者在8(16)位除数时商超过8(16)位,则认为是溢出,引起0号中断。IDIV:有符号除法指令,当除数为0,活着商太大,太小(字节超过127,-127字超过32767,-32767)时,引起0号中断。 符号扩展指令 CBW,CWD:把AL中的符号扩展到寄存器AH中,不影响各标志位。CWD则把AX中的符号扩展到DX,同样不影响标志位。注意:在无符号数除之前,不宜用这两条指令,一般采用XOR 清高8位或高16位。 逻辑运算指令与位移指令 注意:只能有一个存储器操作数;只有通用寄存器或存储器操作数可作为目的操作数,用于存放结果;操作数的类型必须一致。 NOT:取反,不影响标志位。 AND 操作数1 操作数2:操作结果送错作数1,标志CF(进位)、OF(溢出)清0,PF(奇偶)ZF(0标志) SF(符号)反映运算结果,AF(辅助进位)未定义。自己与自己AND值不变,她主要用于将操作数中与1相与的位保持不变,与0相与清0。(都为1时为1)OR 操作数1 操作数2:自己与自己OR值不变,CF(进位)、OF(溢出)清0,PF(奇偶)ZF(0标志)SF(符号)反映运算结果,AF(辅助进位)未定义。她使用于将若干位置1:

汇编通用指令集(含分析)

指令格式(16进制)机器码(2进制)机器码 ADD r/m8,r8 00 /r 00 000 0 0 0 oorrrmmm ADD r/m32,r32 01 /r 00 000 0 0 1 oorrrmmm ADD r/m16,r16 01 /r 00 000 0 0 1 oorrrmmm ADD r8,r/m8 02 /r 00 000 0 1 0 oorrrmmm ADD r16,r/m16 03 /r 00 000 0 1 1 oorrrmmm ADD r32,r/m32 03 /r 00 000 0 1 1 oorrrmmm 前6位全为0 ADD AL, imm8 04 ib 00 000 1 0 0 ib ADD EAX, imm32 05 id 00 000 1 0 1 id ADD AX, imm16 05 iw 00 000 1 0 1 iw 前5位为0,第6,7位为10???第6位为0有MOD域 PUSH ES 06 00 000 1 1 0 POP ES 07 00 000 1 1 1 前5位为0,第6,7位为11 OR r/m8,r8 08 /r 00 001 000 oorrrmmm OR r/m16,r16 09 /r 00 001 001 oorrrmmm OR r/m32,r32 09 /r 00 001 001 oorrrmmm OR r8,r/m8 0A /r 00 001 010 oorrrmmm OR r16,r/m16 0B /r 00 001 011 oorrrmmm

OR r32,r/m32 0B /r 00 001 011 oorrrmmm 前4位为0,第5,6位为10 OR AL, imm8 0C ib 00 001 1 0 0 ib OR EAX, imm32 0D id 00 001 1 0 1 id OR AX, imm16 0D iw 00 001 1 0 1 iw 前4位为0,第5,6位为11 PUSH CS 0E 00 001 1 1 0 这里没有0F 0F是以后用于扩展00 001 1 1 1 ADC r/m8,r8 10 /r 00 010 0 0 0 oorrrmmm ADC r/m32,r32 11 / r 00 010 0 0 1 oorrrmmm ADC r/m16,r16 11 /r 00 010 0 0 1 oorrrmmm ADC r8,r/m8 12 /r 00 010 0 1 0 oorrrmmm ADC r16,r/m16 13 /r 00 010 0 1 1 oorrrmmm ADC r32,r/m32 13 /r 00 010 0 1 1 oorrrmmm 前5位为00010,6、7位为01 ADC AL, imm8 14 ib 00 010 100 ib ADC EAX, imm32 15 id 00 010 101 id ADC AX, imm16 15 iw 00 010 101 iw 前5位为00010,6、7位为10 PUSH SS 16 00 010 1 1 0

PIC8位单片机汇编语言常用指令的识读

PIC8位单片机汇编语言常用指令的识读(上) 各大类单片机的指令系统是没有通用性的,它是由单片机生产厂家规定的,所以用户必须遵循厂家规定的标准,才能达到应用单片机的目的。 PIC 8位单片机共有三个级别,有相对应的指令集。基本级PIC系列芯片共有指令33条,每条指令是12位字长;中级PIC系列芯片共有指令35条,每条指令是14位字长;高级PIC 系列芯片共有指令58条,每条指令是16位字长。其指令向下兼容。 在这里笔者介绍PIC 8位单片机汇编语言指令的组成及指令中符号的功能,以供初学者阅读相关书籍和资料时快速入门。 一、PIC汇编语言指令格式 PIC系列微控制器汇编语言指令与MCS-51系列单片机汇编语言一样,每条汇编语言指令由4个部分组成,其书写格式如下: 标号操作码助记符操作数1,操作数2;注释 指令格式说明如下:指令的4个部分之间由空格作隔离符,空格可以是1格或多格,以保证交叉汇编时,PC机能识别指令。 1 标号与MCS-51系列单片机功能相同,标号代表指令的符号地址。在程序汇编时,已赋以指令存储器地址的具体数值。汇编语言中采用符号地址(即标号)是便于查看、修改,尤其是便于指令转移地址的表示。标号是指令格式中的可选项,只有在被其它语句引用时才需派上标号。在无标号的情况下,指令助记符前面必须保留一个或一个以上的空格再写指令助记符。指令助记符不能占用标号的位置,否则该助记符会被汇编程序作标号误处理。 书写标号时,规定第一字符必须是字母或半角下划线“—”,它后面可以跟英文和数字字符、冒号(:)制符表等,并可任意组合。再有标号不能用操作码助记符和寄存器的代号表示。标号也可以单独占一行。 2 操作码助记符该字段是指令的必选项。该项可以是指令助记符,也可以由伪指令及宏命令组成,其作用是在交叉汇编时,“指令操作码助记符”与“操作码表”进行逐一比较,找出其相应的机器码一一代之。 3 操作数由操作数的数据值或以符号表示的数据或地址值组成。若操作数有两个,则两个操作数之间用逗号(,)分开。当操作数是常数时,常数可以是二进制、八进制、十进制或十六进制数。还可以是被定义过的标号、字符串和ASCⅡ码等。具体表示时,规定在二进制数前冠以字母“B”,例如B10011100;八进制数前冠以字母“O”,例如O257;十进制数前冠以字母“D”,例如D122;十六进制数前冠以“H”,例如H2F。在这里PIC 8位单片机默认进制是十六进制,在十六进制数之前加上Ox,如H2F可以写成Ox2F。 指令的操作数项也是可选项。 PIC系列与MCS-51系列8位单片机一样,存在寻址方法,即操作数的来源或去向问题。因PIC系列微控制器采用了精简指令集(RISC)结构体系,其寻址方式和指令都既少而又简单。其寻址方式根据操作数来源的不同,可分为立即数寻址、直接寻址、寄存器间接寻址和位寻址四种。所以PIC系列单片机指令中的操作数常常出现有关寄存器符号。有关的寻址实例,均可在本文的后面找到。 4 注释用来对程序作些说明,便于人们阅读程序。注释开始之前用分号(;)与其它部分相隔。当汇编程序检测到分号时,其后面的字符不再处理。值得注意:在用到子程序时应说明程序的入口条件、出口条件以及该程序应完成的功能和作用。 二、清零指令(共4条) 1 寄存器清零指令 实例:CLRW;寄存器W被清零 说明:该条指令很简单,其中W为PIC单片机的工作寄存器,相当于MCS-51系列单片机中的累加器A,CLR是英语Clear的缩写字母。 2 看门狗定时器清零指令。 实例:CLRWDT;看门狗定时器清零(若已赋值,同时清预分频器)

MIPS 指令系统和汇编语言

第四章MIPS指令系统和汇编语言 1.考研预测:出题特点总结 本章是对统考408内容来说,本章是新增的章节。此外北航961大纲中制定了要考MIPS 指令集,从15年961真题来看MIPS是重中之重。但是今年计组并没有指定具体的教材,但大纲明确要求掌握MIPS指令集,所以还是建议考生将《计算机组成与设计:硬件/软件接口》中文版(原版第三版或第四版)作为本章的参考书籍。 本章大致内容是MIPS的基础知识,难度并不大。考生应该将重点放在MIPS指令集的基础上,考察C语言中的语句转换为对应的MIPS指令,所以需要熟练掌握C语言中一些语句对应的MIPS指令实现。本章出题很大可能就是C语言和MIPS汇编语言之间的转换,也可能涉及到第五章CPU指令流水线等内容。 2.考研知识点系统整理:梳理考点,各个击破 3.1 指令系统概述 机器指令要素 操作码:指明进行的何种操作 源操作数地址:参加操作的操作数的地址,可能有多个。 目的操作数地址:保存操作结果的地址。 下条指令的地址:指明下一条要运行的指令的位置,一般指令是按顺序依次执行的,所以绝大多数指令中并不显式的指明下一条指令的地址,也就是说,指令格式中并不包含这部分信息。只有少数指令需要显示指明下一条指令的地址。

指令执行周期 3.2 指令格式 一台计算机指令格式的选择和确定要涉及多方面的因素,如指令长度、地址码结构以及操

作码结构等,是一个很复杂的问题,它与计算机系统结构、数据表示方法、指令功能设计等都密切相关。 指令的基本格式 一条指令就是机器语言的一个语句,它是一组有意义的二进制代码,指令的基本格式如下: ( 其中A1为第一操作数地址,A2为第二操作数地址,A3为操作结果存放地址。 这条指令的含义:(A1)OP(A2)→A3 式中OP表示双操作数运算指令的运算符号,如“+”或“–”等。 (2)二地址指令

汇编语言的各条指令

常用命令 数据传送指令 一通用数据传送指令 MOV指令为双操作数指令,两个操作数中不能全为内存操作数 格式:MOV DST,SRC 执行操作:dst = src 注:1.目的数可以是通用寄存器,存储单元和段寄存器(但不允许用CS段寄存器). 2.立即数不能直接送段寄存器 3.不允许在两个存储单元直接传送数据 4.不允许在两个段寄存器间直接传送信息 PUSH入栈指令及POP出栈指令: 堆栈操作是以“后进先出”的方式进行数据操作。 格式:PUSH SRC //Word 执行操作:(SP)<-(SP)-2 ((SP)+1,(SP))<-(SRC) 注:1.入栈的操作数除不允许用立即数外,可以为通用寄存器,段寄存器(全部)和存储器。

2.入栈时高位字节先入栈,低位字节后入栈。 格式:POP DST //Word 执行操作:(DST)<-((SP+1),(SP)) (SP)<-(SP)+2 注:1.出栈操作数除不允许用立即数和CS段寄存器外,可以为通用寄存器,段寄存器和存储器。 2.执行POP SS指令后,堆栈区在存储区的位置要改变。 3.执行POP SP 指令后,栈顶的位置要改变。 XCHG(eXCHanG)交换指令: 将两操作数值交换。 格式:XCHG OPR1,OPR2 //Byte/Word 执行的操作:(OPR1)<-->(OPR2) 注:1.必须有一个操作数是在寄存器中 2.不能与段寄存器交换数据 存储器与存储器之间不能交换数据。 二累加器专用传送指令 IN输入指令 长格式为:IN AL,PORT(字节) IN AX,PORT(字) 执行的操作:(AL)<-(PORT)(字节)

单片机汇编语言指令集

汇编语言的所有指令数据传送指令集 MOV 功能: 把源操作数送给目的操作数 语法: MOV 目的操作数,源操作数 格式: MOV r1,r2 MOV r,m MOV m,r MOV r,data XCHG 功能: 交换两个操作数的数据 语法: XCHG 格式: XCHG r1,r2 XCHG m,r XCHG r,m PUSH,POP 功能: 把操作数压入或取出堆栈 语法: PUSH 操作数POP 操作数 格式: PUSH r PUSH M PUSH data POP r POP m PUSHF,POPF,PUSHA,POPA 功能: 堆栈指令群 格式: PUSHF POPF PUSHA POPA LEA,LDS,LES 功能: 取地址至寄存器 语法: LEA r,m LDS r,m LES r,m XLAT(XLATB) 功能: 查表指令 语法: XLAT XLAT m 算数运算指令 ADD,ADC 功能: 加法指令 语法: ADD OP1,OP2 ADC OP1,OP2 格式: ADD r1,r2 ADD r,m ADD m,r ADD r,data 影响标志: C,P,A,Z,S,O SUB,SBB 功能:减法指令 语法: SUB OP1,OP2 SBB OP1,OP2 格式: SUB r1,r2 SUB r,m SUB m,r SUB r,data SUB m,data 影响标志: C,P,A,Z,S,O

INC,DEC 功能: 把OP的值加一或减一 语法: INC OP DEC OP 格式: INC r/m DEC r/m 影响标志: P,A,Z,S,O NEG 功能: 将OP的符号反相(取二进制补码) 语法: NEG OP 格式: NEG r/m 影响标志: C,P,A,Z,S,O MUL,IMUL 功能: 乘法指令 语法: MUL OP IMUL OP 格式: MUL r/m IMUL r/m 影响标志: C,P,A,Z,S,O(仅IMUL会影响S标志) DIV,IDIV 功能:除法指令 语法: DIV OP IDIV OP 格式: DIV r/m IDIV r/m CBW,CWD 功能: 有符号数扩展指令 语法: CBW CWD AAA,AAS,AAM,AAD 功能: 非压BCD码运算调整指令 语法: AAA AAS AAM AAD 影响标志: A,C(AAA,AAS) S,Z,P(AAM,AAD) DAA,DAS 功能: 压缩BCD码调整指令 语法: DAA DAS 影响标志: C,P,A,Z,S 位运算指令集 AND,OR,XOR,NOT,TEST 功能: 执行BIT与BIT之间的逻辑运算 语法: AND r/m,r/m/data OR r/m,r/m/data XOR r/m,r/m/data TEST r/m,r/m/data NOT r/m 影响标志: C,O,P,Z,S(其中C与O两个标志会被设为0) NOT指令不影响任何标志位 SHR,SHL,SAR,SAL 功能: 移位指令 语法: SHR r/m,data/CL SHL r/m,data/CL SAR r/m,data/CL SAL r/m,data/CL

常见汇编语言指令解释:

PC是一个16位的程序计数器。用于存放和指示下一条要执行的指令的地址。寻址范围达64KB。PC有自动加1功能,以实现程序的顺序执行。PC没有地址,是不可寻址的,无法用指令对它进行读写。但在执行转移、调用、返回等指令时能自动改变其内容,以改变程序的执行顺序。 参数代表的意义: 1、Rn 表示R0~R7中的一个 2、#data 表示8位的数值 00H~FFH 3、direct 表示8位的地址 00H~FFH(指的是内部RAM或SFR的地址) 4、@Ri 表示寄存器间接寻址只能是R0或者R1 5、@DPTR 表示数据指针间接寻址 6、bit 表示位地址 7、$ 表示当前地址 常见汇编语言指令解释: 寄存器寻址 MOV A,R1将R1中的数值赋予A 直接寻址 MOV A,3AH将地址3AH中的数值赋予A 立即寻址 MOV A,#3AH将3AH数值赋予A

寄存器间址 MOV A,@R0 将 R0中地址的数值赋予A 变址寻址 MOVC A,@A+DPTR以A中的数值为地址偏移量进行查表 相对寻址 AJMP MATN跳转到行号为MATN处 位寻址 MOV C,7FH 将位地址7FH的数值赋予C MOV A,#3AH数据传输、赋值命令 PUSH direct将direct为地址的数值压入堆栈中 POP direct将direct为地址的数值弹出堆栈 XCH A,direct将direct中的数值与A进行交换 ADD A,direct将direct中的数值与 INC direct将direct中的数值加1 SUBB A,direct将A中的数值减去direct中的数值和Cy值,并保存在A中,如果想使用不带Cy减法,可以在运算前对Cy清零:CLR C DEC direct将direct中的数值减1 DA A 用于对BCD码加减法后进行10进制调整 MUL A B将A和B相乘,并把高八位放在B中,低八位放在A中 DIV A B将A和B相除,并把商放在A中,余数放在B中 ANL A,direct将A与direct中的数值进行与运算,结果保留在A 中(与运算规律:有0出0,全1出1) ORL A,direct将A与direct中的数值进行或运算,结果保留在A中(或运算规律:有1出1,全0出0) XRL A,direct将A与direct中的数值进行异或运算,结果保留在A 中(异或运算规律:全0出0,全1出0,01、10出1)

相关主题
文本预览
相关文档 最新文档