32位汇编指令总结(代码示例)


通用数据传送指令

MOV 传送字或字节

mov al,10h

MOVSX 先符号扩展,再传送

movsx eax,ax;先进行全零扩展,前16位为F

MOVZX 先零扩展,再传送

movzx eax,ax;先进行全零扩展,前16位为0

PUSH 把字压入堆栈

push reg/nem16   32
push imm32

POP 把字弹出堆栈

pop reg/nem16  32

PUSHFD 把32EFLAGS寄存器内容压入堆栈

pushfd;保存标志寄存器内容

POPFD 把32EFLAGS寄存器内容弹出堆栈

popfd;恢复标志寄存器内容

PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈

pusha;保存16通用寄存器内容

POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈

popa;恢复16通用寄存器内存

PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈

pushad;保存32通用寄存器内容

POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈

popad;恢复32通用寄存器内存

BSWAP 交换32位寄存器里字节的顺序

;EAX=96688368H
BSWAP EAX;EAX=68836896H

XCHG 交换字或字节( 至少有一个操作数为寄存器,段寄存器不可作为操作数)

xchg ax,hx
xchg ah,al
xchg eax,ebx
xchg var,ax;var16位

CMPXCHG 比较并交换操作数( 第二个操作数必须为累加器AL/AX/EAX )

CMPXCHG CX,DX
;如果指令执行前 (AX)=2300H,(CX)=2300H.(DX)=2400H
;则指令执行后 因(CX)=(AX),故(CX)=2400H,ZF=1
;如果指令执行前(AX)=2500H,(CX)=2300H,(DX)=2400H
;则指令执行后因(CX)!=(AX),故(AX)=2300H,ZF=0

XADD 先交换再累加( 结果在第一个操作数里 )

xadd eax,ecx
;相当于:
	先执行:
		xchg eax,ecx
	然后执行:
		add eax,ecx

XLAT 字节查表转换

X DW 1122h,3344h,5566h,7788h
lea bx,X
mov al,03h
xlat

BX 指向一张 256 字节的表的起点, AL 为表的索引值 (0-255,即 0-FFH); 返回 AL 为查表结果 ( [BX+AL]->AL )

输入输出端口传送指令

IN I/O端口输入

语法: IN 累加器, {端口号│DX}

OUT I/O端口输出

语法: OUT {端口号│DX},累加器

输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,其范围是 0-65535

目的地址传送指令

LEA 装入有效地址

LEA DX,string ;把偏移地址存到DX

LDS 传送目标指针,把指针内容装入DS

LDS SI,string ;把段地址:偏移地址存到DS:SI

LES 传送目标指针,把指针内容装入ES

LES DI,string ;把段地址:偏移地址存到ESDI

LFS 传送目标指针,把指针内容装入FS

LFS DI,string ;把段地址:偏移地址存到FSD

LGS 传送目标指针,把指针内容装入GS

LGS DI,string ;把段地址:偏移地址存到GSDI 

LSS 传送目标指针,把指针内容装入SS

LSS DI,string ;把段地址:偏移地址存到SSDI

标志传送指令

LAHF 标志寄存器传送,把标志装入AH

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

SAHF 标志寄存器传送,把AH内容装入标志寄存器

mov ah,saveflags
    sahf

PUSHF 标志入栈

pushf;保存标志寄存器内容

POPF 标志出栈

popf;恢复标志寄存器内容

PUSHD 32位标志入栈

pushd;保存32通用寄存器内容

POPD 32位标志出栈

popd;恢复32通用寄存器内存

算术运算指令

ADD 加法

mov eax,1
add eax,12

ADC 带进位加法

mov dl,0
mov al,0FFh
add al,0FFh;AL=FEh
adc dl,0;DL/AL=01FEh

INC 加 1

mov ax,1
inc ax

AAA 加法的ASCII码调整

mov ah,0
mov al,'8';AX=0038h
add al,'2';AX=006Ah
aaa;AX=0100h(结果进行ASCII转换)
or ax,3030h;AX=3130h='10'(转换为ASCII码)

DAA 加法的十进制调整

mov al,35h
add al,48h;AL=7Dh
daa;AL=83h(调整后结果)

SUB 减法

mov al,23
sub al,3

SBB 带借位减法

mov edx,7;高32位
mov eax,1;低32位
sub eax,2
sbb edx,0;高32位减法

DEC 减 1

dec al

NEC 求反(以 0 减之)

nec al

CMP 比较.(两操作数作减法,仅修改标志位,不回送结果)

mov ax,5
cmp ax,10;ZF=0 and CF=1

AAS 减法的ASCII码调整

mov ah,0
mov al,'8';AX=0038h
sub al,'9';AX=00FFh
aas;AX=FF09h
pushf
or al,30h;AX=FF39h
popf

DAS 减法的十进制调整

mov bl,48h
mov al,85h
sub al,bl;AL=3Dh
das;AL=37h(调整后结果)

MUL 无符号乘法

var word 0100h
mov ax,2000h;AX=2000h;AX存储结果
mul 0100h/var;DX:AX=00200000h,CF=1;32位EDX:EAX

IMUL 整数乘法

mov ax,48
mov bx,4
imul bx;DX:AX=000000C0h,OF=0

以上两条,结果回送AH和AL(字节运算),或DX和AX(字运算)

AAM 乘法的ASCII码调整

var byte 05h,06h
mov bl,var;第一个操作数
mov bl,[var+1];第二个操作数
mul bl;AX=001Eh
aam;AX=0300h

DIV 无符号除法

mov ax,0083h;被除数
mov bl,2;除数
div bl;AL=41h,AH=01h

IDIV 整数除法

var sword -101;009Bh
mov dx,0
mov ax,var;DX:AX=0000009Bh(+155)
mov bx,2;BX是除数
idiv bx;DX:AX除以BX
    
var sword -48
mov al,var;被除数低字节
cbw;AL扩展到AH
mov bl,+5;除数
idiv bl;AL=-9,AH=-3

以上两条,结果回送:

商回送AL,余数回送AH, (字节运算);或商回送AX,余数回送DX, (字运算)

AAD 除法的ASCII码调整

var byte ?
var2 byte ?
mov ax,0307h;被除数
aad;AX=0025h
mov bl,5;除数
div bl;AX=0207h
mov var,al
mov var2,ah

CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)

var sword -101;9Bh
mov al,var;AL=9Bh
cbw;AL=FF9Bh

CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)

var sword -101;FF9Bh
mov ax,var;AX=FF9Bh
cwd;DX:AX=FFFFFF9Bh

CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)

NULL

CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)

var sword -101;FFFFFF9Bh
mov eax,var;EDX:EAX=FFFFFFFFFFFFFF9Bh
cdq

逻辑运算指令

AND 与运算

mov al,10101110b
and al,11110110b;消除位0,3

OR 或运算

mov al,11100011b
or al,00000100b;位2置1

XOR 异或运算

mov al,10110101b
xor al,0;异或

NOT 取反

mov al,10101110b
not al;补集

TEST 测试(两操作数作与运算,仅修改标志位,不回送结果)

test al,00001001b;测试0,3位

SHL 逻辑左移,位元乘法

mov bl,8Fh;BL=10001111b
shl bl,1;CF=1,BL=00011110b

SAL 算术左移(=SHL)

sal/shl

SHR 逻辑右移,位元除法

mov al,0D0h;AL=11010000b
shr al,1;AL=01101000b,CF=0

SAR 算术右移(=SHR)

sar/shr

ROL 循环左移

mov al,40h;AL=01000000b
rol al,1;AL=10000000b
rol al,3;AL=00000100b

ROR 循环右移

mov al,01h;AL=00000001b
ror al,1;AL=10000000b
ror al,3;AL=00010000b

RCL 通过进位的循环左移

clc;CF=0
mov bl,88h;CF,BL=0 10001000b
rcl bl,1;CF,BL=1 00010000b
rcl bl,1;CF,BL=0 00100010b

RCR 通过进位的循环右移

stc ;CF=1
mov ah,10h;AH,CF=00010000 1
rcr ah,1;AH,CF=10001000 0

以上八种移位指令,其移位次数可达255次

移位一次时, 可直接用操作码. 如 SHL AX,1

移位>1次时, 则由寄存器CL给出移位次数

如 MOV CL,04 SHL AX,CL

SHLD 双精度左移

wval word 9BA6h
mov ax,0AC36h
shld wval,ax,4;wval=BA6Ah,将wval左移4位,并把AX的高4位插入wval的低4位

SHRD 双精度右移

mov ax,234Bh
mov dx,7654h
shrd ax,dx,4;AX右移4位,并把DX的低4位插入AX的高4位

串指令

DS:SI 源串段寄存器 :源串变址

NULL

ESI 目标串段寄存器:目标串变址

NULL

CX 重复次数计数器

NULL

AL/AX 扫描值

NULL

D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量

NULL

Z标志 用来控制扫描或比较操作的结束

NULL

MOVS 串传送 ( MOVSB 传送字符 MOVSW 传送字 MOVSD 传送双字 )

;传送字符串数据:将ESI寻址的内存数据复制到EDI寻址的内存位置
;复制双字数值
source dword 20 dup(0FFFFFFFh)
target dword 20 dup(?)
.code
cld;方向为正
mov ecx,lengthof source;设置REP计数器
mov esi,offset source;ESI指向source
mov edi,offset target;EDI指向target
rep movsd;复制双字

CMPS 串比较 ( CMPSB 比较字符 CMPSW 比较字 )

;比较字符串:比较分别由ESI和EDI寻址的内存数据
;比较双字
mov esi OFFSET source
mov edi ,OFFSET target
cld;方向为正向
mov ecx, LENGTHOF source;设置重复计数器
repe cmpsd;相等则重复

SCAS 串扫描 把AL或AX的内容与目标串作比较,比较结果反映在标志位

;扫描字符串:比较累加器(AL、AX和EAX)与EDI寻址的内存数据
;扫描是否有匹配字符
alpha BYTE "ABCDEFGH",0
.code
mov edi,OFFSET alpha;EDI指向字符串
mov al,'F';检索字符F
mov ecx,LENGTHOF alpha;设置检索计数器
cld;方向为正向
repne scasb;不相等则重复
jnz quit;若未发现字符则退出
dec edi;发现字符: EDI减1

LODS 装入串 把源串中的元素(字或字节)逐一装入AL或AX中( LODSB 传送字符 LODSW 传送字 LODSD 传送双字 )

;从字符串加载到累加器:将ESI寻址的内存数据加载到累加器
;数组乘法
:本程序将一个32位整数数组中的每个元素都乘以一个常数。
INCLUDE Irvine32. inc
.data
array DWORD 1,2,3,4,5,6,7,8,9,10;测试数据
multiplier DWORD 10;测试数据
.code
main PROC
    cld;方向为正向
    mov esi,OFFSET array;源数组索引
    mov edi,esi;目标数组索引
    mov ecx,LENGTHOF array;循环计数器
Ll: lodsd;将[ESI]加载到EAX
    mul multiplier;与常数相乘
    stosd;将EAX保存到[EDI]
    loop Ll
    exit
main ENDP
END main

STOS 保存串 是LODS的逆过程

;保存字符串数据L:将累加器内容保存到EDI寻址的内存位置
.data
Count = 100
string1 BYTE Count DUP(?)
.code
mov al,OFFh;要保存的数值
mov edi,OFFSET string1;EDI指向目标字符串
mov ecx,Count;字符计数器
cld;方向为正向
rep stosb;用AL的内容实现填充

REP 当CX/ECX<>0时重复(单个指令处理整个字符串)

rep movsb

REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复

repe cmpsd

REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复

repne scasb

REPC 当CF=1且CX/ECX<>0时重复

repc movsb

REPNC 当CF=0且CX/ECX<>0时重复

repnc movsb

程序转移指令

简单的条件转移指令

JZ(或jE) OPR—————结果为零转移, 测试条件ZF=1;相等跳转

cmp eax,0
jz/je L1;如果ZF=1则跳转

JNZ(或jNE) OPR ————–结果不为零转移,测试条件ZF=0;不等跳转

and dl,10110000b
jnz/jne L2;ZF=0跳转

JS OPR———————-结果为负转移, 测试条件SF=1

SF=1

JNS OPR———————结果为正转移, 测试条件SF=0

SF=0

JO OPR——————— 溢出转移, 测试条件OF=1

OF=1

JNO OPR ——————–不溢出转移 , 测试条件OF=0

OF=0

JP OPR ———————结果为偶转移, 测试条件PF=1

PF=1

JNP OPR ——————–结果为奇转移 , 测试条件PF=0

PF=0

JC OPR ——————– 有进位转移 , 测试条件CF=1

CF=1

JNC OPR ——————–无进位转移, 测试条件CF=0

CF=0

无符号比较条件转移指令(以下指令经常是CMP OPD,OPS后面的指令根据比较结果来实现转移)

JB(或JNAE) opd ————–小于或者不大于等于则转移

小于跳转

JNB(或JAE) opd—————不小于或者大于等于则转移

不小于跳转

JA(或NJBE) OPD—————大于或者不小于等于则转移

mov al,+127
cmp al,-128
    ja/njbe L1;不跳转

JNA(或JBE) OPD—————不大于或者小于等于则转移

mov al,+127
cmp al,-128
    jna/jbe L1;跳转

带符号比较条件转移指令

JL(或JNGE) ————–小于或者不大于等于则转移

mov ax,5
mov ax,6
	jl/jnge L1;跳转

JNL(或JGE)————–不小于或者大于等于则转移

mov edx,-1
cmp edx,0
    jnl/jge L1;不跳转

JG(或NJLE)—————大于或者不小于等于则转移

mov ax,5
cmp ax,4
	jp/njle L1;大于则跳转

JNG(或JLE)—————不大于或者小于等于则转移

mov ecx,0
cmp ecx,0
    jng/jle;跳转

JCXZ

CX=0跳转

JECXZ

ECX=0跳转

JRCXZ

RCX=0跳转

调用子程序与返回指令

CALL 子程序调用指令

call SumOf;调用SumOf过程

RET 子程序返回指令

SumOf proc
    .
    .
    ret
SumOf endp

条件循环指令

LOOP———-按ECX计算器循环

    mov ax,0
    mov ecx,5
L1:
    inc ax
    loop L1;每次循环ax加一,循环5次

LOOPZ————为零跳转

loopz L1

LOOPNZ————–非零跳转

loopnz L1

LOOPE——————-相等跳转

loope L1

LOOPNE——————-不等跳转

loopne L1

.IF .ELSE .ELSEIF .ENDIF

.IF conditionl
    statements
[.ELSELF condition2
	statements]
[ELSE 
	statements]
.ENDIF

.REPEAT .WHILE

.REPEAT 
    statements
.UNTIL condition
    
.WHILE condition
    statements
.ENDW

其它指令

OFFSET ——————– 返回偏移地址

mov esi,offset var1;  esi=00404000h
mov esi,offset var2;  esi=00404000h

SEG ——————– 返回段地址

mov esi,seg var1
mov esi,seg var2

EQU(=) ——————– 等值语句

name EQU expression
name EQU symbol
name EQU <text>
    
pressKey EQU <"Press any key to continue...", 0>
matrix1 EQU 10 * 10
matrix2 EQU <10 * 10>

PURGE ——————– 解除语句

PURGE,标识符1,标识符2,...,标识符n

DUP ——————– 操作数字段用复制操作符

db x dup();x是重复的次数,()里是要重复的数逗号分隔
str1 db 10 dup ('!@#') ;这就是十个!@#
格式:db 重复的次数 dup (重复的内容)
buf1 db 100 dup(?);开辟100个字节的内存区

SEGMENT,ENDS ——————– 段定义指令

segment_name SEGMENT 【定位类型】 【组合类型】 【类别名】
···;here is your code
segment ends

ASSUME ——————– 段地址分配指令

.data
  ........
.code
  ........
  assume cs:code,ds:data
start: .......
  mov ax,data
  mov ds,ax
  ...
ends
end start

ORG ——————– 起始偏移地址设置指令

ORG 0000H
AJMP MAIN
ORG 0030H

$ ——————–地址计数器的当前值

例如JNE+6,能引用地址计数器的值,每次引用会使地址计数器的值发生改变,地址计数器即当前指令的偏移地址。该指令的转向地址即JNE指令的首地址加6。

PROC,ENDP ——————– 过程定义语句

SumOf proc
    .
    .
    .
    ret
SumOf endp;这是一个过程

NAME,TITLE,END ——————– 程序开始结束语句

NULL

MACRO,ENDM ——————–宏定义指令

mPutchar MACRO char
    push eax
    mov al,char
    call WriteChar
    pop eax
    ENDM

XLAT (TRANSLATE) ——————– 换码指令—-

X DW 1122h,3344h,5566h,7788h
lea bx,X
mov al,03h
xlat

ALIGN ———————伪指令

var byte ?; 00404000h
ALIGN 2
var2 byte ?; 00404002

PTR ———————-运算符

var dword 12345678h
mov ax,word ptr var; 将低16位(5678)送入ax

TYPE

var word ?
var2 byte ?; word,byte都是type,分别代表2,1

LENGTHOF ————–运算符

var1 byte 10,20,30;3
var2 word 30 DUP(?),0,0;32
var3 word 5 DUP(3 dup(?));3*5
var4 byte "1234",0;5

SIZFEOF————-运算符

var word 32 dup(0)
mov eax,sizeof var;eax=32*2=64

LABEL —————伪指令

var1 label word
var2 dword 12345678h;公用一个内存位置,var2未分配空间
mov ax,var1;5678h
mov dx,[var+2];1234h

TYPEDEF————–运算符

var typedef ptr byte;(指针)
.data
	array byte 10h,20h,30h
    ptr1 var ?
    ptr2 var array;指向一个数组

JMP ————无条件跳转到目标地址

top:
.
.
    jmp top;不断循环

USES—————等于 push+pop

ArraySum proc uses esi ecx
    mov eax,0
L1:
	add eax,[esi]
    add esi,type dword
    loop L1
ArraySum endp

CLC

clc;清除标识位

STC

进位标志置1

ENTER——————-被调用过程自动创建堆栈帧

Mysub proc
	enter 8,0
;等效于
Mysub proc
	push ebp
	mov ebp,esp
	sub esp,8

LEAVE——————指令结束一个过程的堆栈帧

Mysub proc
	enter 8,0
	.
	.
	leave
	ret
Mysub endp
;等效于
Mysub proc
	push ebp
	mov ebp,esp
	sub esp,8
	.
	.
	mov esp,ebp
	pop ebp
	ret
Mysub endp

LOCAL—————局部变量

Mysub proc
	local var:dword;这是一个局部变量

INVOKE—————–CALL替代品,一行调用多个参数

invoke Dumparray,offset array,lengthof array,type array

ADDR——–只能和INVOKE一起

array dword 20 dup(?)
invoke swap
	addr array
	addr [array+4]

条件标志

ZF 零标志

当结果为负时,SF=1,否则,SF=0

AF 辅助进位标志

运算过程中第三位有进位值,置AF=1,否则,AF=0

PF 奇偶标志

当结果操作数中偶数个"1",置PF=1,否则,PF=0

SF 符号标志

当结果为负时,SF=1;否则,SF=0.溢出时情形例外

CF 进位标志

最高有效位产生进位值,例如,执行加法指令时,MSB有进位,置CF=1;否则,CF=0

OF 溢出标志

若操作数结果超出了机器能表示的范围,则产生溢出,置OF=1,否则,OF=0

文章作者: 0xdadream
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 0xdadream !
评论
  目录