x64汇编指令大全,【一些常用的汇编语言指令】汇编语言cli指令
x64汇编指令大全,【一些常用的汇编语言指令】汇编语言cli指令详细介绍
本文目录一览: 汇编中的常见指令有哪些
关于这个问题,你可以在《Intel? 64 and IA-32 Architectures Software Developer’s Manual》中找到答案!手册可以从INTEL官方站点下载!
手册第一卷第五章第一节,描述了一些通用指令。
汇编语言指令集
汇编指令是汇编语言中使用的一些操作符(如mov,inc,loop)和助记符,还包括一些伪指令(如assume,end)。用于告诉汇编程序如何进行汇编的指令,它既不控制机器的操作也不被汇编成机器代码,只能为汇编程序所识别并指导汇编如何进行。
一、数据传输指令
它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据。
1. 通用数据传送指令
MOV 传送字或字节.
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 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数)
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. 例: LFS DI,string ;把段地址:偏移地址存到FS:DI.
LGS 传送目标指针,把指针内容装入GS. 例: LGS DI,string ;把段地址:偏移地址存到GS:DI.
LSS 传送目标指针,把指针内容装入SS. 例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 标志传送指令.
LAHF 标志寄存器传送,把标志装入AH.
SAHF 标志寄存器传送,把AH内容装入标志寄存器.
PUSHF 标志入栈.
POPF 标志出栈.
PUSHD 32位标志入栈.
POPD 32位标志出栈.
二、算术运算指令
ADD 加法.
ADC 带进位加法.
INC 加 1.
AAA 加法的ASCII码调整.
DAA 加法的十进制调整.
SUB 减法.
SBB 带借位减法.
DEC 减 1.
NEC 求反(以 0 减之).
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).
AAS 减法的ASCII码调整.
DAS 减法的十进制调整.
MUL 无符号乘法.
IMUL 整数乘法.
以上两条,结果回送AH和AL(字节运算),或DX和AX(字运算),
AAM 乘法的ASCII码调整.
DIV 无符号除法.
IDIV 整数除法.
以上两条,结果回送:
商回送AL,余数回送AH, (字节运算);
或 商回送AX,余数回送DX, (字运算).
AAD 除法的ASCII码调整.
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)
三、逻辑运算指令
AND 与运算.
or 或运算.
XOR 异或运算.
NOT 取反.
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
SHL 逻辑左移.
SAL 算术左移.(=SHL)
SHR 逻辑右移.
SAR 算术右移.(=SHR)
ROL 循环左移.
ROR 循环右移.
RCL 通过进位的循环左移.
RCR 通过进位的循环右移.
以上八种移位指令,其移位次数可达255次.
移位一次时, 可直接用操作码. 如 SHL AX,1.
移位>1次时, 则由寄存器CL给出移位次数.
如 MOV CL,04
SHL AX,CL
四、串指令
DS:SI 源串段寄存器 :源串变址.
ES:DI 目标串段寄存器:目标串变址.
CX 重复次数计数器.
AL/AX 扫描值.
D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.
Z标志 用来控制扫描或比较操作的结束.
MOVS 串传送.
( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )
CMPS 串比较.
( CMPSB 比较字符. CMPSW 比较字. )
SCAS 串扫描.
把AL或AX的内容与目标串作比较,比较结果反映在标志位.
LODS 装入串.
把源串中的元素(字或字节)逐一装入AL或AX中.
( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )
STOS 保存串.
是LODS的逆过程.
REP 当CX/ECX<>0时重复.
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复.
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复.
REPC 当CF=1且CX/ECX<>0时重复.
REPNC 当CF=0且CX/ECX<>0时重复.
五、程序转移指令
1>无条件转移指令 (长转移)
JMP 无条件转移指令
CALL 过程调用
RET/RETF过程返回.
2>条件转移指令 (短转移,-128到+127的距离内)
( 当且仅当(SF XOR OF)=1时,OP1
<op2 )
JA/JNBE 不小于或不等于时转移.
JAE/JNB 大于或等于转移.
JB/JNAE 小于转移.
JBE/JNA 小于或等于转移.
以上四条,测试无符号整数运算的结果(标志C和Z).
JG/JNLE 大于转移.
JGE/JNL 大于或等于转移.
JL/JNGE 小于转移.
JLE/JNG 小于或等于转移.
以上四条,测试带符号整数运算的结果(标志S,O和Z).
JE/JZ 等于转移.
JNE/JNZ 不等于时转移.
JC 有进位时转移.
JNC 无进位时转移.
JNO 不溢出时转移.
JNP/JPO 奇偶性为奇数时转移.
JNS 符号位为 "0" 时转移.
JO 溢出转移.
JP/JPE 奇偶性为偶数时转移.
JS 符号位为 "1" 时转移.
3>循环控制指令(短转移)
LOOP CX不为零时循环.
LOOPE/LOOPZ CX不为零且标志Z=1时循环.
LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.
JCXZ CX为零时转移.
JECXZ ECX为零时转移.
4>中断指令
INT 中断指令
INTO 溢出中断
IRET 中断返回
5>处理器控制指令
HLT 处理器暂停, 直到出现中断或复位信号才继续.
WAIT 当芯片引线TEST为高电平时使CPU进入等待状态.
ESC 转换到外处理器.
LOCK 封锁总线.
NOP 空操作.
STC 置进位标志位.
CLC 清进位标志位.
CMC 进位标志取反.
STD 置方向标志位.
CLD 清方向标志位.
STI 置中断允许位.
CLI 清中断允许位.
六、伪指令
DW 定义字(2字节).
PROC 定义过程.
ENDP 过程结束.
SEGMENT 定义段.
ASSUME 建立段寄存器寻址.
ENDS 段结束.
END 程序结束.
七、处理机控制指令:
标志处理指令 CLC(进位位置0指令)
CMC(进位位求反指令)
STC(进位位置为1指令)
CLD(方向标志置1指令)
STD(方向标志位置1指令)
CLI(中断标志置0指令)
STI(中断标志置1指令)
NOP(无操作)
HLT(停机)
WAIT(等待)
ESC(换码)
LOCK(封锁)
【一些常用的汇编语言指令】汇编语言cli指令
汇编语言常用指令
大家在做免杀或者破解软件的时候经常要用到汇编指令,本人整理出了常用的 希望对大家有帮助!
数据传送指令
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:
与1相或为1,保持不变的位与0相或。(都为0时为0)
XOR 操作数1 操作数2:自己与自己异或结果为0,标志CF (进位)、OF (溢出)清0,PF (奇偶)ZF (0)SF (符号)反映运算结果,AF (辅助进位)未定义。主要用于将若干位取反的操作:与1异或取反,与0异或保持不变。(相同为0,不同为1)
TEST 操作数1 操作数2:测试指令,和AND 相同,但结果不送操作数1,各标志位同AND 操作。
位移指令
SAL/SHL 操作数 1或CL :算术左移与逻辑左移进行相同的动作,操作数是通用寄存器或者存储器操作数,位移数为1或为CL ;最高位移CF (进位),右边用0补位。左移一次相当源操作数乘2。
SAR 操作数 1或CL :算术右移,位移数为1或为CL ;操作数是通用寄存器或者存储器操作数,左符号位保持不变,移出最低位进CF (进位)。相当源操作数除2。
SHR 操作数 1或CL :逻辑右移,操作数是通用寄存器或者存储器操作数,位移数为1或为CL ;左边用0补足,移出的最低位进CF (进位)对于无符号数,右移一位相当于除2。 ROL/ROR 操作数 1或CL : 不带进位左移/右移,操作数是通用寄存器或者存储器操作数,位移数为1或为CL 。
RCL/RCR 操作数 1或CL : 带进位左移/右移,CF (进位)参与循环。操作数是通用寄存器或者存储器操作数,位移数为1或为CL 。
转移指令
注意:由于代码段可分为多个段,所以根据转移时是否重置代码段寄存器CS 内容,可分为段内转移和段间转移。段内转移仅重置IP 的转移,转移后指令仍在同一代码段中。段间转移重置CS ,所以转移后继续执行的指令在另一个段中。
JMP 标号 :无条件跳转到标号位置执行,段内直接转移指令。地址差用一个字节表示为短转移,用一个字表示为近转移。
JMP 通用寄存器/存储单元:无条件段间间接转移指令,操作数给定的是目标地址处。 JMP FAR PTR 标号:无条件段间直接转移指令,她的具体动作是把指令中包含的目标地址的段值和偏移分别置茹CS 和IP 。
JMP 操作数:无条件段间间接转移指令,操作数是双字存储单元,给定目标地址,低字节送IP ,高字节送CS 。
条件转移指令:所有的条件转移指令都是段内转移。她是由J 加上相应的含义字母组合成。有符号数关系G (大于),E (等于),L (小于);无符号数关系A (高于)、E (等于)和B (低于);字母N 表示“不”:NB (不小于),NE (不等于)。
循环指令
LOOP 标号:她使寄存器CX 减1,若结果不等于0则转到标号,否则顺序执行LOOP 指令后的指令。最多循环65536次。
LOOPE/LOOPZ 标号:等于/全零循环指令。CX 的值减1,如果结果不等于0,并且ZF (0标志)等于1,则转移到标号。
LOOPNE/LOOPNZ 标号:不等于/非零循环指令,CX 的值减1,如果结果不等于0,并且ZF (0标志)等于0,则跳转到标号。
JCXZ 标号: 该指令实现当寄存器CX 的值等于0转移到标号,否则顺序执行。通常该指令用在循环开始前,以便在循环次数位0时,跳过循环体。
汇编基础知识六
这里开始熟悉汇编的指令格式
下图为X86版本的指令格式,X64的指令格式和X86差不多后面有需要的话再详细写
Istruction Prefixes : 可选项
默认二进制文件是前缀和内容混杂在一起只有机器才能识别区别
人工区分方法:
X86格式图已经给我们提示,有四个组,一次最多使用一个组
段前缀指令的作用: 修改使用段寄存器
不加提示默认使用DS
如果有栈寄存器的话会使用SS
push ebp是设置程序为X86位下的16位模式情况下运行
CPU是如何判断程序有关系:
CS中有一个DB位如果CS中DB位为0则16位1位32
现在默认的CPU模式是32位,所以汇编指令就算是使用epb(16位寄存器)最少也是32位
如何使用16位的
只需要在硬编码前面加上前缀 66:即可
效果如上面
当CPU使用32位模式选址方式就会使用32位进行
当DB位为0的时候16位,使用16位寻址方式,当DB为1的时候使用32位寻址方式
决定 硬编码长度是由( Opcode ModR/M SIB )决定。前缀指令只会影响到他自己。
然后,ModR/M 由Opcode决定 SIB由ModR/M决定
虽然这个是叫做One-byte但是都是从这个表里面展开的
由这个图例查找,55,push rbp/13
然后 0F-3F都有两个操作符,前面的是Opcode,后面跟着是ModR/M
如果Opcode跟着 ModR/M的话就是变长,没有则定长
所有两个操作符的就判定前面的是Opcode,ModR/M
这是要理解这个我们可以查询他相关的问题操作符解释
在Intell白皮书里面有Codes for addressing method
可以查到操作符大写解释
下面的Codes for Operand Type
有操作符小写解释
例如大写E前面很明显的写了A ModR/M byte follows the opcode
表中寄存器带个r表示可以随着系统变化而变化,可以是64位的RAX,也可以是32位的EAX,也可以是AX 表中会显示最大的修改位数,带E开头的表示只能修改32位和16位
ERX=EAX or ECX or EDX 等通用寄存器
硬编码 4开头是 INC/DEC 5开头的是push/pop
0-7是 INC PUSH
8-F是DEC POP
40开头的都两行格式,上面的一行表示32位,下面的是64位的。
在b开头的是mov指令
他的写法又不一样,mov AL\R8L,Ib
这样能够很好的解释定长指令不是只有一个字节的
I是Immedlate立即数
b是bate 字节
v是 word doubleword quadword三种情况之一,他取决于你采用数据宽度
所以:
0-7 是 mov rb,lb
8-F 是 mov ERX,Iv
9开头 就是XCHG指令是两个寄存器之间交换而且都是放到EAX中
例:
但0是表示EAX 用EAX放到EAX中所以汇编中把
90作为nop 不做任何操作。
我们通常使用Nop的时候是遇到花指令这个下次有时间再写。
90-97是有规则的,但8-F单独说
表格中如果带有
I64 指令表示这个指令在64位下单独表示,例如INC和DEC
o64 只能在64位系统下使用。
d64 这个指令默认是64位,且不支持32位
f64 在64位操作系统下强制使用64位宽度
能够修改EIP的指令有JCC,call,ret三类
从上表中可以查到JCC的指令可以从 0x70~0x7F,八个指令。
上图是JCC指令示例
不论是70-7F中哪一个都会带有一个字节的数据,那个数据被称为偏移地址。
所以JCC普通跳转地址最大位一个字节(FF/2),80以下往下跳转,80以上往上跳转
条件跳转,后面跟一个字节立即数的偏移(有符号),共两个字节
如果条件成立调到当前指令地址+当前指令长度+LB
最大值:向前跳转7F,向后跳转80
而且当你要跳转的字节超过一个字节就会跳转到两个字节,
0F80 者就是两个字节,0F上会让你去看两字节的表同样书中会有这个表格
因为E指令有多个指令包含JMP,CALL,LOOP
J是 带偏移地址
上面的是常用的不常用的先不写了
MODR/M 只占一个字节八个位拆开就是下面:
经典的边长指令:
G(寄存器)是由ModR/M 中3,4,5位Reg/Opcode 决定的表格如下
E(寄存器)是由ModR/M中的0,1,2,6,7位Mod和R/M共同决定的:
注:
现在我们查一下一些不常用的指令的指令
0x80~0x83 首先是Imediate Grp 1^1A
1A的意思是下面的表格
1A就是 3,4,5不再代表通用寄存器,而是通用寄存器
所有的带有这些角标的都可以看扩展
Grp 1是下面的表格
具体的所有变长指令的表基本介绍完了,我们试试查找一下
81 22 08 FF
81 Ev,Iz
72 拆成字节是
0111 0010
根据ModR/M
01 110 010
结合 81 MOD 和 R/M 三个可以查出
XXX WORD ptr ds:[EDP+disp8],[immediate]
再用 reg查完整的就是
XOR WORD PTR DS:[EDP+disp8],Iz
这里还有两个未知数不知道 就是后面的数据
disp8是08 Iz就是FF
上面有提过:
当查ModR/M表查到--时,就表示ModR/M不能完全确定寄存器需要再跟一个字节来确定,这个字节就是SIB
例如:
88 84 48
Mov [--][--]+disp32,AL
SIB计算是这下面计算的
然后根据上面的数据可以查出
48
0100 1000
01 001 000
base 000 index 001 Scale 01
硬编码整个过程来说,就是简略的通过查表了解CPU将数据转化成汇编指令的过程。
如何操作rax,rbx,rcx,rdx等64位寄存器
写一个a.c的程序,然后 g++ -S -o a.s a.c
查看一下x64平台上的汇编指令就可以了。
上面的方法是你比较熟悉ia32平台指令的情况下。
另外可以去intel的官网,下载intel的开发手册,自己查询x64的指令。
64位和32位的汇编风格是一样的,都是at&t风格,只是在指令的数据长度和常用寄存器不一样。
比如ia32 的pushl指令,在x64后就是pushq
比如,要让rax=1,那就是 movss $1, %rax
ARM64汇编指令
blr : 带反回的跳转指令,照转到指令后边跟随寄存器中保存的地址;
mov :将某一寄存器的值复制到另一个寄存器(只能用于寄存器与寄存器或者寄存器与常量之间传值,不能用于内存地址), 如:
mov x1, x0 将寄存器x0的值复制到寄存器x1中;
ldr :将内存中的值读取到寄存器中,如:
ldr x0, [x1, x2] 将寄存器x1和寄存器x2相加作为地址,取该内存地址的值放入寄存器x0中;
str : 将寄存器中的值写入到内存中, 如:
str x0, [x0, x8] 将寄存器x0的值保存到内存[x0 + x8]处;
bl : 跳转到某地址
求汇编指令大全~
我认为我认为我认为我认为我认为我认为我认为我认为我认为 line 1:指定编译时codesg分配给代码段寄存器line 2:定义代码段line 3、4:定义数据段起始地址0020hline 5:bl清0line 6:若没有loop,就是简单地将40h送cx,若有loop,实质是定义了循环次数为40hline 7:bl内的值送[bx]内存放的内存地址。所以,这里不是将bl的值直接送bx存放,是存放到bx中存放的地址指向的存储单元。line 8:bl内的值加1line 9:判断cx是否为0(这里是隐形判断),非0,继续跳转到s处执行语句line 10、11:调用4ch号功能,执行21h中断,程序将返回DOS系统。
8086/8088指令系统
一、数据传送指令
1.通用数据传送指令
MOV(Move)传送
PUSH(Push onto the stack)进栈
POP(Pop from the stack)出栈
XCHG(Exchange)交换
.MOV 指令
格式为: MOV DST,SRC
执行的操作:(DST)<-(SRC)
.PUSH 进栈指令
格式为:PUSH SRC
执行的操作:(SP)<-(SP)-2
((SP)+1,(SP))<-(SRC)
.POP 出栈指令
格式为:POP DST
执行的操作:(DST)<-((SP+1),(SP))
(SP)<-(SP)+2
.XCHG 交换指令
格式为:XCHG OPR1,OPR2
执行的操作:(OPR1)<-->(OPR2)
2.累加器专用传送指令
IN(Input) 输入
OUT(Output) 输出
XLAT(Translate) 换码
这组指令只限于使用累加器AX 或AL 传送信息.
.IN 输入指令
长格式为: IN AL,PORT(字节)
IN AX,PORT(字)
执行的操作: (AL)<-(PORT)(字节)
(AX)<-(PORT+1,PORT)(字)
短格式为: IN AL,DX(字节)
IN AX,DX(字)
执行的操作: AL<-((DX))(字节)
AX<-((DX)+1,DX)(字)
.OUT 输出指令
长格式为: OUT PORT,AL(字节)
OUT PORT,AX(字)
执行的操作: (PORT)<-(AL)(字节)
(PORT+1,PORT)<-(AX)(字)
短格式为: OUT DX,AL(字节)
OUT DX,AX(字)
执行的操作: ((DX))<-(AL)(字节)
((DX)+1,(DX))<-AX(字)
在IBM-PC 机里,外部设备最多可有65536个I/O 端口,端口(即外设的端口地址)为
0000~FFFFH.其中前256个端口(0~FFH)可以直接在指令中指定,这就是长格式中的PORT,此
时机器指令用二个字节表示,第二个字节就是端口号.所以用长格式时可以在指定中直接指定
端口号,但只限于前256个端口.当端口号>=256时,只能使用短格式,此时,必须先把端口号放到
DX 寄存器中(端口号可以从0000到0FFFFH),然后再用IN 或OUT 指令来传送信息.
.XLAT 换码指令
格式为: XLAT OPR
或: XLAT
执行的操作:(AL)<-((BX)+(AL))
3.有效地址送寄存器指令
LEA(Load effective address)有效地址送寄存器
LDS(Load DS with Pointer)指针送寄存器和DS
LES(Load ES with Pointer)指针送寄存器和ES
.LEA 有效地址送寄存器
格式为: LEA REG,SRC
执行的操作:(REG)<-SRC
指令把源操作数的有效地址送到指定的寄存器中.
.LDS 指针送寄存器和DS 指令
格式为: LDS REG,SRC
执行的操作:(REG)<-(SRC)
(DS)<-(SRC+2)
把源操作数指定的4个相继字节送到由指令指定的寄存器及DS 寄存器中.该指令常指定
SI 寄存器.
.LES 指针送寄存器和ES 指令
格式为: LES REG,SRC
执行的操作: (REG)<-(SRC)
(ES)<-(SRC+2)
把源操作数指定的4个相继字节送到由指令指定的寄存器及ES 寄存器中.该指令常指定
DI 寄存器.
4.标志寄存器传送指令
LAHF(Load AH with flags)标志送AH
SAHF(store AH into flags)AH 送标志寄存器
PUSHF(push the flags) 标志进栈
POPF(pop the flags) 标志出栈
.LAHF 标志送AH
格式为: LAHF
执行的操作:(AH)<-(PWS 的低字节)
.SAHF AH 送标志寄存器
格式为: SAHF
执行的操作:(PWS 的低字节)<-(AH)
.PUSHF 标志进栈
格式为: PUSHF
执行的操作:(SP)<-(SP)-2
((SP)+1,(SP))<-(PSW)
.POPF 标志出栈
格式为: POPF
执行的操作:(PWS)<-((SP)+1,(SP))
(SP)<-(SP+2)
二、算术指令
1.加法指令
ADD(add)加法
ADC(add with carry)带进位加法
INC(increment)加1
.ADD 加法指令
格式: ADD DST,SRC
执行的操作:(DST)<-(SRC)+(DST)
.ADC 带进位加法指令
格式: ADC DST,SRC
执行的操作:(DST)<-(SRC)+(DST)+CF
.ADD 加1指令
格式: INC OPR
执行的操作:(OPR)<-(OPR)+1
2.减法指令
SUB(subtract)减法
SBB(subtract with borrow)带借位减法
DEC(Decrement)减1
NEG(Negate)求补
CMP(Compare)比较
.SUB 减法指令
格式: SUB DST,SRC
执行的操作:(DST)<-(DST)-(SRC)
.SBB 带借位减法指令
格式: SBB DST,SRC
执行的操作:(DST)<-(DST)-(SRC)-CF
.DEC 减1指令
格式: DEC OPR
执行的操作:(OPR)<-(OPR)-1
.NEG 求补指令
格式: NEG OPR
执行的操作:(OPR)<- -(OPR)
.CMP 比较指令
格式: CMP OPR1,OPR2
执行的操作:(OPR1)-(OPR2)
该指令与SUB 指令一样执行减法操作,但不保存结果,只是根据结果设置条件标志西半
球.
3.乘法指令
MUL(Unsigned Multiple)无符号数乘法
IMUL(Signed Multiple)带符号数乘法
.MUL 无符号数乘法指令
格式: MUL SRC
执行的操作:
字节操作数:(AX)<-(AL)*(SRC)
字操作数:(DX,AX)<-(AX)*(SRC)
.IMUL 带符号数乘法指令
格式: IMUL SRC
执行的操作:与MUL 相同,但必须是带符号数,而MUL 是无符号数.
4.除法指令
DIV(Unsigned divide)无符号数除法
IDIV(Signed divide)带符号数除法
CBW(Convert byte to word)字节转换为字
CWD(Contert word to double word)字转换为双字
.DIV 无符号数除法指令
格式: DIV SRC
执行的操作:
字节操作:(AL)<-(AX)/(SRC)的商
(AH)<-(AX)/(SRC)的余数
字操作: (AX)<-(DX,AX)/(SRC)的商
(AX)<-(DX,AX)/(SRC)的余数
.IDIV 带符号数除法指令
格式: DIV SRC
执行的操作:与DIV 相同,但操作数必须是带符号数,商和余数也均为带符号数,且余数的符号
与被除数的符号相同.
.CBW 字节转换为字指令
格式: CBW
执行的操作:AL 的内容符号扩展到AH.即如果(AL)的最高有效位为0,则(AH)=00;如(AL)的最
高有效位为1,则(AH)=0FFH
.CWD 字转换为双字指令
格式: CWD
执行的操作:AX 的内容符号扩展到DX.即如(AX) 的最高有效位为0, 则(DX)=0;否则
(DX)=0FFFFH.
这两条指令都不影响条件码.
三、逻辑指令
1.逻辑运算指令
AND(and) 逻辑与
OR(or) 逻辑或
NOT(not) 逻辑非
XOR(exclusive or)异或
TEST(test) 测试
.AND 逻辑与指令
格式: AND DST,SRC
执行的操作:(DST)<-(DST)^(SRC)
.OR 逻辑或指令
格式: OR DST,SRC
执行的操作:(DST)<-(DST)V(SRC)
.NOT 逻辑非指令
格式: NOT OPR
执行的操作:(OPR)<-(OPR)
.XOR 异或指令
格式: XOR DST,SRC
执行的操作:(DST)<-(DST)V(SRC)
.TEST 测试指令
格式: TEST OPR1,OPR2
执行的操作:(DST)^(SRC)
两个操作数相与的结果不保存,只根据其特征置条件码
2.移位指令
SHL(shift logical left) 逻辑左移
SAL(shift arithmetic left) 算术左移
SHR(shift logical right) 逻辑右移
SAR(shift arithmetic right) 算术右移
ROL(Rotate left) 循环左移
ROR(Rotate right) 循环右移
RCL(Rotate left through carry) 带进位循环左移
RCR(Rotate right through carry) 带进位循环右移
格式: SHL OPR,CNT(其余的类似)
其中OPR 可以是除立即数以外的任何寻址方式.移位次数由CNT 决定,CNT 可以是1或CL.
循环移位指令可以改变操作数中所有位的位置;移位指令则常常用来做乘以2除以2操作.
其中算术移位指令适用于带符号数运算,SAL 用来乘2,SAR 用来除以2;而逻辑移位指令则用
来无符号数运算,SHL 用来乘2,SHR 用来除以2.
四、串处理指令
1.与REP 相配合工作的MOVS,STOS 和LODS 指令
.REP 重复串操作直到(CX)=0为上
格式: REP string primitive
其中String Primitive 可为MOVS,LODS 或STOS 指令
执行的操作:
1)如(CX)=0则退出REP,否则往下执行.
2)(CX)<-(CX)-1
3)执行其中的串操作
4)重复1)~3)
.MOVS 串传送指令
格式:可有三种
MOVS DST,SRC
MOVSB(字节)
MOVSW(字)
其中第二、三种格式明确地注明是传送字节或字,第一种格式则应在操作数中表明是字还是
字节操作,例如:
MOVS ES:BYTE PTR[DI],DS:[SI]
执行的操作:
1)((DI))<-((SI))
2)字节操作:
(SI)<-(SI)+(或-)1,(DI)<-(DI)+(或-)1
当方向标志DF=0时用+,当方向标志DF=1时用-
3)字操作:
(SI)<-(SI)+(或-)2,(DI)<-(DI)+(或-)2
当方向标志DF=0时用+,当方向标志DF=1时用-
该指令不影响条件码.
.CLD(Clear direction flag)该指令使DF=0,在执行串操作指令时可使地址自动增量;
.STD(Set direction flag)该指令使DF=1,在执行串操作指令时可使地址自动减量.
.STOS 存入串指令
格式: STOS DST
STOSB(字节)
STOSW(字)
执行的操作:
字节操作:((DI))<-(AL),(DI)<-(DI)+-1
字操作: ((DI))<-(AX),(DI)<-(DI)+-2
该指令把AL 或AX 的内容存入由(DI)指定的附加段的某单元中,并根据DF 的值及数据类型
修改DI 的内容,当它与REP 联用时,可把AL 或AX 的内容存入一个长度为(CX)的缓冲区中.
.LODS 从串取指令
格式: LODS SRC
LODSB
LODSW
执行的操作:
字节操作:(AL)<-((SI)),(SI)<-(SI)+-1
字操作: (AX)<-((SI)),(SI)<-(SI)+-2
该指令把由(SI)指定的数据段中某单元的内容送到AL 或AX 中,并根据方向标志及数据类型
修改SI 的内容.指令允许使用段跨越前缀来指定非数据段的存储区.该指令也不影响条件码.
一般说来,该指令不和REP 联用.有时缓冲区中的一串字符需要逐次取出来测试时,可使
用本指令.
2.与REPE/REPZ 和REPNZ/REPNE 联合工作的CMPS 和SCAS 指令
.REPE/REPZ 当相等/为零时重复串操作
格式: REPE(或REPZ) String Primitive
其中String Primitive 可为CMPS 或SCAS 指令.
执行的操作:
1)如(CX)=0或ZF=0(即某次比较的结果两个操作数不等)时退出,否则往下执行
2)(CX)<-(CX)-1
3)执行其后的串指令
4)重复1)~3)
.REPNE/REPNZ 当不相等/不为零时重复串操作
格式: REPNE(或REPNZ) String Primitive
其中String Primitive 可为CMPS 或SCAS 指令
执行的操作:
除退出条件(CX=0)或ZF=1外,其他操作与REPE 完全相同.
.CMPS 串比较指令
格式: CMP SRC,DST
CMPSB
CMPSW
执行的操作:
1)((SI))-((DI))
2)字节操作:(SI)<-(SI)+-1,(DI)<-(DI)+-1
字操作: (SI)<-(SI)+-2,(DI)<-(DI)+-2
指令把由(SI)指向的数据段中的一个字(或字节)与由(DI)指向的附加段中的一个字(或字节)
相减,但不保存结果,只根据结果设置条件码,指令的其它特性和MOVS 指令的规定相同.
.SCAS 串扫描指令
格式: SCAS DST
SCASB
SCASW
执行的操作:
字节操作:(AL)-((DI)),(DI)<-(DI)+-1
字操作: (AL)-((DI)),(DI)<-(DI)+-2
该指令把AL(或AX)的内容与由(DI)指定的在附加段中的一个字节(或字)进行比较,并不保存
结果,只根据结果置条件码.指令的其他特性和MOVS 的规定相同.
五、控制转移指令
1.无条件转移指令
.JMP(jmp) 跳转指令
1)段内直接短转移
格式:JMP SHORT OPR
执行的操作:(IP)<-(IP)+8位位移量
2)段内直接近转移
格式:JMP NEAR PTR OPR
执行的操作:(IP)<-(IP)+16位位移量
3)段内间接转移
格式:JMP WORD PTR OPR
执行的操作:(IP)<-(EA)
4)段间直接(远)转移
格式:JMP FAR PTR OPR
执行的操作:(IP)<-OPR 的段内偏移地址
(CS)<-OPR 所在段的段地址
5)段间间接转移
格式:JMP DWORD PTR OPR
执行的操作:(IP)<-(EA)
(CS)<-(EA+2)
2.条件转移指令
1)根据单个条件标志的设置情况转移
.JZ(或JE)(Jump if zero,or equal) 结果为零(或相等)则转移
格式:JE(或JZ) OPR
测试条件:ZF=1
.JNZ(或JNE)(Jump if not zero,or not equal) 结果不为零(或不相等)则转移
格式:JNZ(或JNE) OPR
测试条件:ZF=0
.JS(Jump if sign) 结果为负则转移
格式: JS OPR
测试条件:SF=1
.JNS(Jump if not sign) 结果为正则转移
格式:JNS OPR
测试条件:SF=0
.JO(Jump if overflow) 溢出则转移
格式: JO OPR
测试条件:OF=1
.JNO(Jump if not overflow) 不溢出则转移
格式: JNO OPR
测试条件:OF=0
.JP(或JPE)(Jump if parity,or parity even) 奇偶位为1则转移
格式: JP OPR
测试条件:PF=1
.JNP(或JPO)(Jump if not parity,or parity odd) 奇偶位为0则转移
格式: JNP(或JPO) OPR
测试条件:PF=0
.JB(或JNAE,JC)(Jump if below,or not above or equal,or carry) 低于,或者不高于或等于,或进位
位为1则转移
格式:JB(或JNAE,JC) OPR
测试条件:CF=1
.JNB(或JAE,JNC)(Jump if not below,or above or equal,or not carry) 不低于,或者高于或者等于,
或进位位为0则转移
格式:JNB(或JAE,JNC) OPR
测试条件:CF=0
2)比较两个无符号数,并根据比较的结果转移
.JB(或JNAE,JC)
格式:同上
.JNB(或JAE,JNC)
格式:同上
.JBE(或JNA)(Jump if below or equal,or not above) 低于或等于,或不高于则转移
格式:JBE(或JNA) OPR
测试条件:CFVZF=1
.JNBE(或JA)(Jump if not below or equal,or above) 不低于或等于,或者高于则转移
格式:JNBE(或JA) OPR
测试条件:CFVZF=0
3)比较两个带符号数,并根据比较的结果转移
.JL(或LNGE)(Jump if less,or not greater or equal) 小于,或者不大于或者等于则转移
格式:JL(或JNGE) OPR
测试条件:SFVOF=1
.JNL(或JGE)(Jump if not less,or greater or equal)不小于,或者大于或者等于则转移
格式:JNL(或JGE) OPR
测试条件:SFVOF=0
.JLE(或JNG)(Jump if less or equal,or not greater) 小于或等于,或者不大于则转移
格式:JLE(或JNG) OPR
测试条件:(SFVOF)VZF=1
.JNLE(或JG)(Jump if not less or equal,or greater) 不小于或等于,或者大于则转移
格式:JNLE(或JG) OPR
测试条件:(SFVOF)VZF=0
4)测试CX 的值为0则转移指令
.JCXZ(Jump if CX register is zero) CX 寄存器的内容为零则转移
格式:JCXZ OPR
测试条件:(CX)=0
注:条件转移全为8位短跳!
3.循环指令
.LOOP 循环指令
格式: LOOP OPR
测试条件:(CX)<>0
.LOOPZ/LOOPE 当为零或相等时循环指令
格式: LOOPZ(或LOOPE) OPR
测试条件:(CX)<>0且ZF=1
.LOOPNZ/LOOPNE 当不为零或不相等时循环指令
格式: LOOPNZ(或LOOPNE) OPR
测试条件:(CX)<>0且ZF=0
这三条指令的步骤是:
1)(CX)<-(CX)-1
2)检查是否满足测试条件,如满足则(IP)<-(IP)+D8的符号扩充.
4.子程序
.CALL 调用指令
.RET 返回指令
5.中断
.INT 指令
格式: INT TYPE
或INT
执行的操作:(SP)<-(SP)-2
((SP)+1,(SP))<-(PSW)
(SP)<-(SP)-2
((SP)+1,(SP))<-(CS)
(SP)<-(SP)-2
((SP)+1,(SP))<-(IP)
(IP)<-(TYPE*4)
(CS)<-(TYPE*4+2)
.INTO 若溢出则中断
执行的操作:若OF=1则:
(SP)<-(SP)-2
((SP)+1,(SP))<-(PSW)
(SP)<-(SP)-2
((SP)+1,(SP))<-(CS)
(SP)<-(SP)-2
((SP)+1,(SP))<-(IP)
(IP)<-(10H)
(CS)<-(12H)
.IRET 从中断返回指令
格式: IRET
执行的操作:(IP)<-((SP)+1,(SP))
(SP)<-(SP)+2
(CS)<-((SP)+1,(SP))
(SP)<-(SP)+2
(PSW)<-((SP)+1,(SP))
(SP)<-(SP)+2
六、处理机控制指令
1.标志处理指令
.CLC 进位位置0指令(Clear carry)CF<-0
.CMC 进位位求反指令(Complement carry)CF<-CF
.STC 进位位置1指令(Set carry)CF<-1
.CLD 方向标志置0指令(Clear direction)DF<-0
.STD 方向标志置1指令(Set direction)DF<-1
.CLI 中断标志置0指令(Clear interrupt)IF<-0
.STI 中断标志置1指令(Set interrupt)IF<-0
2.其他处理机控制指令
NOP(No Opreation) 无操作
HLT(Halt) 停机
WAIT(Wait) 等待
ESC(Escape) 换码
LOCK(Lock) 封锁
这些指令可以控制处理机状态.这们都不影响条件码.
.NOP 无操作指令
该指令不执行任何操作,其机器码占有一个字节,在调试程序时往往用这条指令占有一定
的存储单元,以便在正式运行时用其他指令取代.
.HLT 停机指令
该指令可使机器暂停工作,使处理机处于停机状态以便等待一次外部中断到来,中断结束
后可继续执行下面的程序.
.WAIT 等待指令
该指令使处理机处于空转状态,它也可以用来等待外部中断的发生,但中断结束后仍返回
WAIT 指令继续德行.
.ESC 换码指令
格式ESC mem
其中mem 指出一个存储单元,ESC 指令把该存储单元的内容送到数据总线去.当然ESC 指令
不允许使用立即数和寄存器寻址方式.这条指令在使用协处理机(Coprocessor)执行某些操作
时,可从存储器指得指令或操作数.协处理机(如8087)则是为了提高速度而可以选配的硬件.
.LOCK 封锁指令
该指令是一种前缀,它可与其他指令联合,用来维持总线的锁存信号直到与其联合的指令
执行完为止.当CPU 与其他处理机协同工作时,该指令可避免破坏有用信息.
求汇编语言的所有指令?
数据传送指令集
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
影响标志: C,P,Z,S,O
ROR,ROL,RCR,RCL
功能: 循环移位指令
语法: ROR r/m,data/CL ROL r/m,data/CL RCR r/m,data/CL RCL r/m,data/CL
影响标志: C,P,Z,S,O
程序流程控制指令集
CLC,STC,CMC
功能: 设定进位标志
语法: CLC STC CMC
标志位: C
CLD,STD
功能: 设定方向标志
语法: CLD STD
标志位: D
CLI,STI
功能: 设定中断标志
语法: CLI STI
标志位: I
CMP
功能: 比较OP1与OP2的值
语法: CMP r/m,r/m/data
标志位: C,P,A,Z,O
JMP
功能: 跳往指定地址执行
语法: JMP 地址
JXX
功能: 当特定条件成立则跳往指定地址执行
语法: JXX 地址
注:
A: ABOVE,当C=0,Z=0时成立
B: BELOW,当C=1时成立
C: CARRY,当弁时成立 CXZ: CX寄存器的值为0(ZERO)时成立
E: EQUAL,当Z=1时成立
G: GREATER(大于),当Z=0且S=0时成立
L: LESS(小于),当S不为零时成立
N: NOT(相反条件),需和其它符号配合使用
O: OVERFLOW,O=1时成立
P: PARITY,P=1时成立
PE: PARITY EVEN,P=1时成立
PO: PARITY ODD,P=0时成立
S: SIGN,S=1时成立
Z: ZERO,Z=1时成立
LOOP
功能: 循环指令集
语法: LOOP 地址
LOOPE(Z)
地址 LOOPNE(Z) 地址
标志位: 无
CALL,RET
功能: 子程序调用,返回指令
语法: CALL 地址 RET RET n
标志位: 无
INT,IRET
功能: 中断调用及返回指令
语法: INT n IRET
标志位: 在执行INT时,CPU会自动将标志寄存器的值入栈,在执行IRET时则会将堆栈中的标志值弹回寄存器
字符串操作指令集
MOVSB,MOVSW,MOVSD
功能: 字符串传送指令
语法: MOVSB MOVSW MOVSD
标志位: 无
CMPSB,CMPSW,CMPSD
功能: 字符串比较指令
语法: CMPSB CMPSW CMPSD
标志位: C,P,Z,S,O
SCASB,SCASW
功能: 字符串搜索指令
语法: SCASB SCASW
标志位: C,P,Z,S,O
LODSB,LODSW,STOSB,STOSW
功能: 字符串载入或存贮指令
语法: LODSB LODSW STOSB STOSW
标志位: 无
REP,REPE,REPNE
功能: 重复前缀指令集
语法: REP 指令S REPE 指令S REPNE 指令S
标志位: 依指令S而定
对于IBM PC机它有它的指令系统,其中包括:数据传送指令、串处理指令、算术指令、控制移动指令、逻辑指令、处理机控制指令。
这里将简单介绍其指令类型及指令说明,如有要求给具体的指令格式及应用,请与amay联系,amay加以更新。
1)数据传送指令:负责把数据、地址或立即数传送到寄存器或存储单元中。
数据传送指令类型 指 令 说 明
通用数据传送指令 MOV(传送)、PUSH(进栈)、POP(出栈)、XCHG(交换)
累加器专用传送指令 IN(输入指令) 、OUT(输入指令)
地址传送指令 LEA(有效地址送寄存器)、LDS(指针送寄存器和DS)、LES(指针送寄存器和ES)
标志寄存器传送指令 LAHF(标志送AH)、SAHF(AH送标志寄存器)、PUSHF(标志进栈)、POPF(标志出栈)
2)算术指令:用来执行算术运算。
算术指令类型 指 令 说 明
加法指令 ADD(加法)、ADC(带进位加法)、INC(加1)
减法指令 SUB(减法)、SBB(带借位减法)、DEC(减1)、NEG(求补)、CMP(比较)
乘法指令 MUL(无符号数乘法)、IMUL(带符号数乘法)
除法指令 DIV(无符号数除法)、IDIV(带符号数除法)、CBW(字节转换为字)、CWD(字转换为双字)
3)逻辑指令:对字或字节执行逻辑运算。
逻辑指令类型 指 令 说 明
逻辑运算指令 AND(逻辑与)、OR(逻辑或)、NOT(逻辑非)、XOR(异或)、TEST(测试)
移动指令 SHL(逻辑左移)、SAL(算术左移)、SHR(逻辑右移)、SAR(算术右移)、ROL(循环左移)、ROR(循环右移)、RCL(带进位循环左移)、RCR(带进位右移)
4)串处理指令:处理存放存储器里的数据串。
串处理指令类型 指 令 说 明
指 令 MOVS(串传送)、CMPS(串比较)、SCAS(串扫描)、LODS(从串取)、STOS(存入串)
5)控制转移指令:用来控制程序的执行流程。
控制转移指令类型 指 令 说 明
无条件转移指令 JMP(段间和段内转移)
条件转移指令 JZ(结果为0(或相等)则转移)、JS(结果为负则转移)、JNS(结果为正则转移)、JO(溢出则转移)、JNO(不溢出则转移)、JP(奇偶位为1则转移)、JNP(奇偶位为0则转移)
循环指令 LOOP(循环指令)、LOOPPZ/LOOPE(当为0或相等时循环指令)、LOOPNZ/LOOPNE(当不为0或不相等时循环指令)
子程序指令 CALL(调用指令)、RET(返回指令)
中断指令 INT(中断)、INTO(如溢出则中断)、RIET(从中断返回)
6)处理机控制指令:
处理机控制指令类型 指 令 说 明
标志处理指令 CLC(进位位置0指令)、CMC(进位位求反指令)、STC(进位位置为1指令)、CLD(方向标志置1指令)、STD(方向标志位置1指令)、CLI(中断标志置0指令)、STI(中断标志置1指令)
其他处理机控制指令 NOP(无操作)、HLT(停机)、WAIT(等待)、ESC(换码)、LOCK(封锁)
参考:http://www.bilayu.com/
汇编语言常用指令
单片机汇编语言汇编错误原因分析
汇编语言的指令格式,目前有两种不同的标准:Windows下的汇编语言基本上都遵循Intel风格的语法,比如:MASM、NASM;而Unix/Linux下的汇编语言基本上都遵循AT&T风格的语法;
一、汇编语言语句的通用格式
[名称[:]] 指令码 [第一操作数][,第二操作数] ;注释
汇编语言的指令码的操作数的个数可以是0、1、2个;当操作数的个数为2的时候,语句还有两种不同的格式:
Windows下Intel风格的汇编语言语句格式为:
[名称[:]] 指令码 目的操作数DST,源操作数SRC ;注释
Unix/Linux下AT&T风格的汇编语言语句格式为:
[名称[:]] 指令码 源操作数SRC,目的操作数DST ;注释
例如: CYCLE: ADD AX,02H ;(AX)汇编语言语句格式中的"名称"并不是所有语句都必需的,但是,如果语句中带有"名称",那么,大多数情况下,"名称"都表示的是内存中某一存储单元的地址,也就是"名称"后面各项在内存中存放的第一个存储单元的地址(包括该"名称"所在段的段地址和段内偏移地址);比如上面的指令中,CYCLE就是该语句的名称,CYCLE表示的就是其后面的机器指令码在内存中存放的第一个地址;"名称"与指令码之间的分隔符可以是冒号":",也可以是空格字符" ";当以冒号分割时,该名称代表的是一个标号;当以空格分割时,该名称代表的可能是标号,也可能是变量;当指令码有多个操作数的时候,相邻两个操作数之间要用逗号","分割;指令码与操作数之间必须以空格分割;汇编语言语句的注释必须以分号";"开头;
二、组成语句的元素
1、常数:
汇编语言中的常数有整数、字符串;二进制、八进制、十进制、十六进制;汇编语言采用不同的后缀区分:
B:二进制数; O:八进制数; D:十进制数; H:十六进制数;
当一个数值后面没有后缀的时候,默认为十进制数;
字符串常数是用一对单引号('')括起来的一串字符;
2、表达式:
由操作数和操作符组成;
算数运算操作符: +、-、*、/、MOD,等;取模运算MOD是取两数相除的余数;
逻辑运算操作符: AND(逻辑与)、OR(逻辑或)、NOT(逻辑非)、XOR(逻辑异或);
注意:逻辑运算符同时又可以是逻辑运算指令的指令码,只有当它们出现在指令的操作数部分时,才是操作符;例如:
ADD AL,0CH ADD 0FH ;第一个ADD是指令码,第二个ADD是操作符;
关系运算操作符: EQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于等于)、GE(大于等于);
汇编语言中的表达式不能单独构成语句,只能是语句的组成部分;
注意:语句中表达式的求值不是在语句执行时完成的,而是在对源程序进行汇编链接时完成的.所以,语句中各表达式的值必须在汇编或链接时就是确定的,也就是说,表达式中各标识符的值在汇编或链接时就应该是确定的;
3、标号:
标号是由标识符表示的指令的名称,用于指示对应指令的位置(地址);
标号具有三个属性:段地址、偏移地址和类型;
标号的段地址和偏移地址属性是指该标号所对应的指令所在段的段地址和段内偏移地址;
标号的类型有两种:NEAR和FAR;标号定义成NEAR类型,表示该标号在段内使用,而定义成FAR类型则表示该标号可以在段间使用;
标号的定义:在指令码前面加上标识符和冒号":";
例如:START: PUSH DS
这条语句里面,START就是我们定义的标号,它代表指令PUSH的地址,所以,标号可以作为程序转移指令的操作数(即:要转向的地址);标号还可以采用伪指令来定义;例如:用LABEL伪指令和过程定义伪指令来定义;
4、变量:
与高级语言一样,并不是所有的操作数都是常数,汇编语言也有自己的变量,变量的值在程序运行期间是可以被改变的;
A.定义变量:汇编语言中,变量的定义是通过伪指令来完成的;定义变量的伪指令格式如下:
变量名 DB 表达式 ;定义字节变量,又称单字节变量(1个连续字节),DB-->BYTE
变量名 DW 表达式 ;定义字变量,又称双字节变量(2个连续字节),DW-->WORD
变量名 DD 表达式 ;定义双字变量,又称四字节变量(4个连续字节),DD-->DWORD
变量名 DF 表达式 ;定义六字节变量,又称六字节变量(6个连续字节),DF-->FWORD
变量名 DQ 表达式 ;定义长字变量,又称八字节变量(8个连续字节),DQ-->QWORD
变量名 DT 表达式 ;定义十字节变量(10个连续字节),DT-->TBYTE;
其中,变量名是一个合法的标识符,变量名后面不能加冒号":",只能用空格;变量名不是必要的,可有可无;变量的类型由关键字DB、DW、DD、DQ、DT来定义;
变量定义语句中的"表达式"是用于对变量进行初始化的,可有一下几种情况:
(1).一个或多个常数或表达式;当为多个常数或表达式时,期间要用逗号隔开;如DATA1--DATA4;
(2).带单引号的字符串;
对于字节型(DB)变量,每个变量的大小为1个字节,每个变量的值不能超过1个字符,每个字节内存入一个字符的ASCII码值,整个字符串可以在同一对单引号内给出,这相当于是定义了一个字符数组,如DATA5;
对于字类型(DW)变量,每个变量的大小为2个字节,每个变量的值不能超过2个字符,若为2个字符时,同样遵循高位存入高字节,低位存入低字节的规则;若为1个字符,则该字符的ASCII码值存入到低字节,高字节为00,如DATA6;
对于双字类型(DD)变量,每个变量的大小为4个字节,每个变量的值不能超过2个字符,若为2个字符,同样遵循高位存入高字节,低位存入低字节的规则;但是2个字符的值被存入到双字变量的最低2个字节中,1个字符的值被存入到双字变量的最低1个字节中;
对于长字类型(DQ)变量,每个变量的大小为8个字节,每个变量的值不能超过2个字符,若为2个字符,同样遵循高位存入高字节,低位存入低字节的规则;但是2个字符的值被存入到长字变量的最低2个字节中,1个字符的值被存入到长字变量的最低1个字节中;
(3).一个问号"?",表示该变量的值不确定,即:该变量所表示的内存单元中的内容是不确定的,或者说是,当表达式为问号时,变量所对应的内存区中并没有存入新的值,而只是预留出了相应的存储空间;如DATA7、DATA8
(4).重复方式;此时的格式为: 重复次数 DUP(表达式);重复方式指出表达式的值可以重复地存储到变量对应的内存区中,重复的次数由伪指令给出,相当于定义数组;如DATA9、DATA10
定义变量的例子:
DATA1 DB 20H ;1字节变量
DATA2 DW 0204H,1000H ;2字节变量
DATA3 DB (-1*3),(15/3) ;1字节变量
DATA4 DD 123456H ;4字节变量
DATA5 DB '0123' ;字符串变量,相当于一个字符数组
DATA6 DW 'AB','C','D' ;字符串变量,相当于一个字符串数组;
DATA7 DB ? ;1字节变量,未初始化
DATA8 DD ? ;4字节变量,未初始化
DATA9 DB 5 DUP(0) ;1字节变量,用5个0初始化,相当于是一个具有5个DB型元素的数组
DATA10 DW 3 DUP(?) ;2字节变量,未初始化,相当于是一个具有3个DW型元素的数组
变量定义语句中伪指令的功能是在变量名所对应的地址开始的内存区依次存入表达式中的各项值,表达式中的每项值所占用内存字节数与变量的类型对应;
总结:一个变量的变量名实际上就代表了该变量所对应的内存区在内存段中的有效地址(偏移地址);高地址是指地址值相对较大,低地址是指地址值相对较小,高地址与低地址是相对而言的;
5、变量的属性:
(1).属性介绍
一个变量具有一下属性:
A.段地址(SEG):变量所在段的段地址;
B.偏移地址(OFFSET):变量所在段内的偏移地址;
C.类型(TYPE):变量的类型定义了每个变量所占用的内存字节数,对于DB、DW、DD、DQ、DT类型定义的变量所占用的内存字节数分别是1、2、4、8、10;通常又将DB、DW、DD类型所定义的变量分别成为BYTE类型、WORD类型、DWORD类型变量;
常用标识符的类型值列表:
标识符种类 字节变量 字变量 双字变量 近标号NEAR 远标号FAR
TYPE的值 1 2 4 -1 -2
D.长度(LENGTH):变量定义时,一个变量名所定义的变量个数;在含有DUP操作符的变量定义中,变量名所定义的变量个数为定义格式中的重复次数;在其它各种变量定义中,每个变量名所定义的变量个数均为1个;
E.大小(SIZE):变量定义语句中,分配给同一个变量名的所有变量的总的字节数,其值为该变量的类型与长度的成绩;
其中,段地址、偏移地址和类型属性是变量的主属性,而长度和大小属性是变量的辅助属性;
(2).属性操作符:
操作符 表达式 含义
SEG SEG 变量名或标号 取出变量名或标号所在段的段地址
OFFSET OFFSET 变量名或标号 取出变量名或标号所在段内的偏移地址
TYPE TYPE 变量名或标号 取出变量名或标号的类型(变量所占用的字节数)
LENGTH LENGTH 变量名 取出变量的长度
SIZE SIZE 变量名 取出变量的大小
这些操作符不能单独构成语句,只能作为表达式的组成部分,并且表达式的求值也是在汇编过程中完成的;
6.强制类型转换操作符PTR
格式:数据类型 PTR 地址表达式
格式中的"数据类型"可以是BYTE、WORD、DWORD、NEAR、FAR;前三种类型是变量的类型,后两种类型是标号的类型;格式中的表达式可以是变量、标号、其它地址表达式;
PTR操作符的功能是用来重新定义已定义的变量或标号的类型,其作用域只在当前语句中; 例如:
DATA1 DW 02H
MOV BYTE PTR DATA1,AL
这条指令中,是把DATA1的类型转换为BYTE类型,然后把AL中的内容存放到DATA1的最低一个字节中;作用域只在这条MOV语句中,过了这条语句,DATA1仍然是DW类型,即:DATA1原来的类型并没有被修改;
汇编语言的几个简单指令,并附上中文解释
常用汇编指令: 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段寄存器中。
汇编语言指令
8086汇编指令手册
一、数据传输指令
它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.
1. 通用数据传送指令.
MOV 传送字或字节.
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 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数)
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.
例: LFS DI,string ;把段地址:偏移地址存到FS:DI.
LGS 传送目标指针,把指针内容装入GS.
例: LGS DI,string ;把段地址:偏移地址存到GS:DI.
LSS 传送目标指针,把指针内容装入SS.
例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 标志传送指令.
LAHF 标志寄存器传送,把标志装入AH.
SAHF 标志寄存器传送,把AH内容装入标志寄存器.
PUSHF 标志入栈.
POPF 标志出栈.
PUSHD 32位标志入栈.
POPD 32位标志出栈.
二、算术运算指令
———————————————————————————————————————
ADD 加法.
ADC 带进位加法.
INC 加 1.
AAA 加法的ASCII码调整.
DAA 加法的十进制调整.
SUB 减法.
SBB 带借位减法.
DEC 减 1.
NEC 求反(以 0 减之).
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).
AAS 减法的ASCII码调整.
DAS 减法的十进制调整.
MUL 无符号乘法.
IMUL 整数乘法.
以上两条,结果回送AH和AL(字节运算),或DX和AX(字运算),
AAM 乘法的ASCII码调整.
DIV 无符号除法.
IDIV 整数除法.
以上两条,结果回送:
商回送AL,余数回送AH, (字节运算);
或 商回送AX,余数回送DX, (字运算).
AAD 除法的ASCII码调整.
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)
三、逻辑运算指令
———————————————————————————————————————
AND 与运算.
OR 或运算.
XOR 异或运算.
NOT 取反.
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
SHL 逻辑左移.
SAL 算术左移.(=SHL)
SHR 逻辑右移.
SAR 算术右移.(=SHR)
ROL 循环左移.
ROR 循环右移.
RCL 通过进位的循环左移.
RCR 通过进位的循环右移.
以上八种移位指令,其移位次数可达255次.
移位一次时, 可直接用操作码. 如 SHL AX,1.
移位>1次时, 则由寄存器CL给出移位次数.
如 MOV CL,04
SHL AX,CL
四、串指令
———————————————————————————————————————
DS:SI 源串段寄存器 :源串变址.
ES:DI 目标串段寄存器:目标串变址.
CX 重复次数计数器.
AL/AX 扫描值.
D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.
Z标志 用来控制扫描或比较操作的结束.
MOVS 串传送.
( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )
CMPS 串比较.
( CMPSB 比较字符. CMPSW 比较字. )
SCAS 串扫描.
把AL或AX的内容与目标串作比较,比较结果反映在标志位.
LODS 装入串.
把源串中的元素(字或字节)逐一装入AL或AX中.
( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )
STOS 保存串.
是LODS的逆过程.
REP 当CX/ECX<>0时重复.
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复.
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复.
REPC 当CF=1且CX/ECX<>0时重复.
REPNC 当CF=0且CX/ECX<>0时重复.
五、程序转移指令
———————————————————————————————————————
1>无条件转移指令 (长转移)
JMP 无条件转移指令
CALL 过程调用
RET/RETF过程返回.
2>条件转移指令 (短转移,-128到+127的距离内)
( 当且仅当(SF XOR OF)=1时,OP1
<op2 )
JA/JNBE 不小于或不等于时转移.
JAE/JNB 大于或等于转移.
JB/JNAE 小于转移.
JBE/JNA 小于或等于转移.
以上四条,测试无符号整数运算的结果(标志C和Z).
JG/JNLE 大于转移.
JGE/JNL 大于或等于转移.
JL/JNGE 小于转移.
JLE/JNG 小于或等于转移.
以上四条,测试带符号整数运算的结果(标志S,O和Z).
JE/JZ 等于转移.
JNE/JNZ 不等于时转移.
JC 有进位时转移.
JNC 无进位时转移.
JNO 不溢出时转移.
JNP/JPO 奇偶性为奇数时转移.
JNS 符号位为 "0" 时转移.
JO 溢出转移.
JP/JPE 奇偶性为偶数时转移.
JS 符号位为 "1" 时转移.
3>循环控制指令(短转移)
LOOP CX不为零时循环.
LOOPE/LOOPZ CX不为零且标志Z=1时循环.
LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.
JCXZ CX为零时转移.
JECXZ ECX为零时转移.
4>中断指令
INT 中断指令
INTO 溢出中断
IRET 中断返回
5>处理器控制指令
HLT 处理器暂停, 直到出现中断或复位信号才继续.
WAIT 当芯片引线TEST为高电平时使CPU进入等待状态.
ESC 转换到外处理器.
LOCK 封锁总线.
NOP 空操作.
STC 置进位标志位.
CLC 清进位标志位.
CMC 进位标志取反.
STD 置方向标志位.
CLD 清方向标志位.
STI 置中断允许位.
CLI 清中断允许位.
六、伪指令
———————————————————————————————————————
DW 定义字(2字节).
PROC 定义过程.
ENDP 过程结束.
SEGMENT 定义段.
ASSUME 建立段寄存器寻址.
ENDS 段结束.
END 程序结束.