0. 存储指令
语法:
mov 寄存器,寄存器
mov 寄存器,[偏移地址]
mov [偏移地址],寄存器
mov ds:[偏移地址],寄存器
1. 加法指令
add 加法
语法:
add 目的操作数,源操作数
执行的操作:目的操作数 <- 目的操作数 + 源操作数
实例:
assume cs:daima
daima segment
mov ax,1000H
mov bx,2000H
add bx,ax
mov ax,4c00H
int 21H
daima ends
end
inc 加1
语法:
inc 操作数
执行的操作:操作数 <- 操作数 + 1
实例:
assume cs:daima
daima segment
mov ax,1000H
inc ax
add bx,ax
mov ax,4c00H
int 21H
daima ends
end
2. 减法指令
sub 加法
语法:
sub 目的操作数,源操作数
执行的操作:目的操作数 <- 目的操作数 - 源操作数
实例:
assume cs:daima
daima segment
mov ax,5000H
mov bx,3000H
sub ax,bx
mov ax,4c00H
int 21H
daima ends
end
dec 加1
语法:
dec 操作数
执行的操作:操作数 <- 操作数 - 1
实例:
assume cs:daima
daima segment
mov ax,1001H
dec ax
mov ax,4c00H
int 21H
daima ends
end
加减法汇总实例
;段地址偏移地址2000-2005中依次放入数据FF、FE、FC、FB、FA
assume cs:daima
daima segment
mov ax,2000H
mov ds,ax
mov bx,0000H
mov ah,0FFH
mov [bx],ah
inc bx
dec ah
mov [bx],ah
inc bx
dec ah
mov [bx],ah
inc bx
dec ah
mov [bx],ah
inc bx
dec ah
mov [bx],ah
mov ax,4c00H
int 21H
daima ends
end
3. 循环指令
loop 循环指令(for)
语法:
loop 标号
执行步骤:
a 将cx寄存器中的值减1
b 判断cx寄存器中的值是否为0.不为0转至标号处执行程序,为0向下执行。
标号:在汇编程序中,为指令的位置标记。
模型:
mov cx,循环次数
标号:
循环体
loop 标号
实例
assume cs:daima
daima segment
mov ax,0000H
mov cx,2H
A:
inc zx
loop A
mov ax,4c00H
int 21H
daima ends
end
;段地址偏移地址2000-2005中依次放入数据FF、FE、FC、FB、FA
assume cs:daima
daima segment
mov ax,2000H
mov ds,ax
mov bx,0000H
mov ah,0FFH
mov [bx],ah
mov cx,4H
A:
inc bx
dec ah
mov [bx],ah
loop A
mov ax,4c00H
int 21H
daima ends
end
4. 乘法指令
MUL
作用:乘法运算
格式:MUL (寄存器 | 内存单元)
8位乘数时,被乘数在AL内,乘积将存储在AX内。
assume cs:code,ds:data
data segment
data ends
stack segment
stack ends
code segment
start:
mov bl,16H
mov al,17H
mul bl ;ds:[00H]
mov ax,4c00H
int 21H
code ends
end start
8位实例:
;8位乘法
assume cs:code,ds:data
data segment
db 03H,04H
dw 0FFH
data ends
stack segment
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov al,ds:[0]
mov ah,ds:[1]
mul ah
mov ds:[2],ax
mov ax,4c00H
int 21H
code ends
end start
16位乘数时,被乘数在AX内,乘积在DX,AX内,遵循高存高,低存低原则。(DX存放高位,AX存放低位)
assume cs:code,ds:data
data segment
data ends
stack segment
stack ends
code segment
start:
mov bx,0FFFFH
mov aX,0FFFFH
mul bx
mov ax,4c00H
int 21H
code ends
end start
5. 除法指令
DIV
作用:除法运算。
格式:DIV (寄存器 | 内存单元)
8位除数时,被除数在AX内,商在AL内,余数在AH内。
assume cs:code,ds:data
data segment
data ends
stack segment
stack ends
code segment
start:
mov ax,4DH
mov bl,0AH
div bl
mov ax,4c00H
int 21H
code ends
end start
16位除数时,被除数在DX和AX内,商在AX内,余数在DX内。(DX存放高位,AX存放低位)
assume cs:code,ds:data
data segment
data ends
stack segment
stack ends
code segment
start:
mov dx,000FH
mov ax,0001H
mov bx,03E8H
div bx
mov ax,4c00H
int 21H
code ends
end start
16位实例:
;16位除法
assume cs:code,ds:data
data segment
dd 00015F99H
dw 0384H,0H,0H
db 0FFH
data ends
stack segment
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov dx,ds:[2]
mov ax,ds:[0]
mov bx.ds:[4]
div bx
;div word ptrbx ds:[4]
mov ds:[6],ax
mov ds:[8],dx
mov ax,4c00H
int 21H
code ends
end start
6. jmp无条件跳转指令(自己理解为go to语句,向前向后跳转均可)
作用:无条件转移指令,可以只修改IP,也可以同时修改CS和IP。
段内短转移(移动范围:-128~127) JMP SHORT 标号(占两个字节)
段内近转移(移动范围:-32768~32767) JMP NEAR PTR 标号(占3个字节)
红箭头表示占字节几位,也就是取值范围大小。
实例:
assume cs:code,ds:data
data segment
data ends
stack segment
stack ends
code segment
start:
mov ax,bx
jmp short s0 ;取值范围小
;jmp near ptr s0 ;取值范围大
mov ax,bx
mov ax,bx
s0:
mov bx,cx
mov bx,cx
mov bx,cx
mov ax,4c00H
int 21H
code ends
end start
jmp指令段间转移
作用:无条件转移指令,可以只修改IP,也可以同时修改CS和IP。
段间远转移 JMP FAR PTR 标号(占5个字节)
FAR PTR 指明了转移指令用标号的段地址和偏移地址修改CS和IP。
assume cs:code,ds:data
data segment
data ends
stack segment
stack ends
abc segment
s1:
mov bx,cx
mov bx,cx
mov bx,cx
ends abc
code segment
start:
mov ax,bx
jmp far ptr s1 ;abc段中的s1
s0:
mov cx,dx
mov cx,dx
mov cx,dx
mov ax,4c00H
int 21H
code ends
end start
jmp指令转移地址
转移地址可以在寄存器中
JMP 寄存器(16位)(段内转移)
assume cs:code,ds:data
data segment
data ends
stack segment
stack ends
code segment
start:
mov ax,bx
mov ax,offset s0
jmp ax
mov bx,cx
s0:
mov cx,dx
mov ax,4c00H
int 21H
code ends
end start
转移地址可以在内存中(自己感觉像if语句的语法,通过判断跳转内存某内存位置)
JMP WORD PTR 内存单元地址(段内转移)
assume cs:code,ds:data
data segment
dw 0000H,0FFFFH
data ends
stack segment
stack ends
code segment
start:
mov ax.data
mov ds,ax
mov ax,offset s0
mov ds:[0],ax
jmp word ptr ds:[0]
mov bx,cx
s0:
mov cx,dx
mov ax,4c00H
int 21H
code ends
end start
JMP DWORD PTR 内存单元地址(段间转移)(跳转到段地址2233,偏移量为0011的位置)
assume cs:code,ds:data
data segment
dw 0000H,0000H,0FFFFH
data ends
stack segment
stack ends
abc segment
mov ax,bx
s0:
mov ax,bx
mov ax,bx
ends abc
code segment
start:
mov ax.data
mov ds,ax
mov bx,abc
mov ds:[0002H],bx
mov bx,offset s0
mov ds:[0],bx
jmp dowrd ptr ds:[0]
mov ax,4c00H
int 21H
code ends
end start
7. jcxz有条件跳转指令(if语句,判断cx寄存器是否为0)
作用:有条件转移指令。段内短转移,范围为:-128~127。
格式:JCXZ 标号
解释:如果CX寄存器的值为0,则转移到标号处执行。
实例1:
assume cs:code,ds:data
data segment
data ends
stack segment
stack ends
code segment
start:
mov ax,bx
mov ax,bx
mov cx,0H
jcxz s0
mov ax,bx
mov ax,bx
s0:
mov bx,cx
mov ax,4c00H
int 21H
code ends
end start
实例2:
;判断cx寄存器是否为0,不为0返回s0,否则执行s1,实现了loop循环功能
assume cs:code,ds:data,ss:stack
data segment
dw 2H.2H,2H,0H,2H,2H
data ends
stack segment
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov bx,0
s0:
mov cx,ds:[bx]
jcxz s1
add bx,2H
jmp s0
s1:
mov dx,bx
mov ax,4c00H
int 21H
code ends
end start
8. RET与RETF指令(跳转)
RET指令
RET指令取栈中的数据,修改IP寄存器的内容,从而实现近转移。
;取出栈60-2地址位数据1111(2个字节),将CS的IP指针赋值为1111,栈同时做了pop,SP指针恢复到60H.
assume cs:code,ds:data,ss:stack
data segment
data ends
stack segment
dw 256 dup [0H]
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,60H
mov ax,1111H
push ax
ret
mov ax,4c00H
int 21H
code ends
end start
RETF指令
RETF指令取栈中的数据,修改CS和IP寄存器的内容,从而实现远转移。
;取出1122放入cs,3344放入ip,恢复至sp为60
assume cs:code,ds:data,ss:stack
data segment
data ends
stack segment
dw 256 dup [0H]
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,60H
mov ax,1122H
mov bx,3344H
push ax
push bx
retf
mov ax,4c00H
int 21H
code ends
end start
9. CALL指令(跳转,形成子程序)
语法:CALL 标号(与ret配合使用形成子程序)
作用:将IP寄存器的值进栈,然后转到标号处执行指令。
;一个简单的子程序设计完成了
assume cs:code,ds:data,ss:stack
data segment
data ends
stack segment
dw 256 dup (0H)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,60H
mov ax,bx
call s0
mov ax,bx ;将ax,bx地址放入ss的005e中,跳转到s0
mov ax,4c00H
int 21H
s0:
mov bx,cx
mov bx,cx
ret ;恢复,从而形成子程序
code ends
end start
CALL指令与段间转移
语法:CALL FAR PTR 标号(与retf配合使用形成子程序)
作用:将CS寄存器、IP寄存器进栈,然后转到标号处执行指令。
assume cs:code,ds:data,ss:stack
data segment
data ends
stack segment
dw 256 dup (0H)
stack ends
code segment
start:
mov ax,stcak
mov ss,ax
mov sp,60H
mov ax,bx
call far ptr s0 ;先将cs值放入ss,再将ip值放入ss,ss中存放2个字
mov ax,bx
mov ax,bx
s0:
mov bx,cx
mov bx,cx
retf
mov ax,4c00H
int 21H
code ends
end start
CALL指令与寄存器
作用:将IP寄存器的值进栈,然后转到寄存器值的位置执行指令。
assume cs:code,ds:data,ss:stack
data segment
data ends
stack segment
dw 256 dup (0H)
stack ends
code segment
start:
mov ax,stcak
mov ss,ax
mov sp,60H
mov ax,bx
mov cx,offset s0 ;将标号存放入寄存器,在call寄存器达到跳转
call cx
mov ax,bx
s0:
mov bx,cx
mov bx,cx
ret
mov ax,4c00H
int 21H
code ends
end start
CALL指令与内存
语法:CALL WORD PTR 内存单元地址(ret配合使用)
作用:将IP寄存器的值进栈,然后转到内存单元所存储值的位置执行指令。
assume cs:code,ds:data,ss:stack
data segment
dw 256 dup (0H)
data ends
stack segment
dw 256 dup (0H)
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,stcak
mov ss,ax
mov sp,60H
mov word ptr ds:[0H],offset s0 ;将s0放入数据段内存偏移地址中
mov ax,bx
call word ptr ds:[0H] ;跳转ds的偏移地址存储的代码
mov ax,bx
s0:
mov bx,cx
mov bx,cx
ret
mov ax,4c00H
int 21H
code ends
end start
语法:CALL DWORD PTR 内存单元地址(retf配合使用)
作用:将CS寄存器、IP寄存器进栈,然后转到内存单元所存储值的位置执行指令。
assume cs:code,ds:data,ss:stack
data segment
dw 256 dup (0H)
data ends
stack segment
dw 256 dup (0H)
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,stcak
mov ss,ax
mov sp,60H
mov word ptr ds:[0H],offset s0 ;将s0放入数据段内存偏移地址中
mov word ptr ds:[2H],offset code ;放入代码段cs值放入ds内存
mov ax,bx
call dword ptr ds:[0H] ;跳转ds的偏移地址存储的代码
mov ax,bx
s0:
mov bx,cx
mov bx,cx
retf
mov ax,4c00H
int 21H
code ends
end start
10. ADC指令(区别ADD指令)
ADC指令:带进位加法指令。
作用:在计算加法的时候,一同带上CF标志位上的进位值进行计算。
;1AFFFF + 2CFFFC = ?
assume cs:code,ds:data,ss:stack
data segment
dw 256 dup (0H)
data ends
stack segment
dw 256 dup (0H)
stack ends
code segment
start:
mov ax,1AH
mov bx,0FFFFH
mov cx,2CH
mov dx,0FFFCH
add bx,dx
adc ax,cx
mov ax,4c00H
int 21H
code ends
end start
11. SBB指令
SBB指令:带借位减法指令。
作用:在计算减法的时候,一同带上CF标志位上的借位值进行计算。
ADC指令:带进位加法指令。
作用:在计算加法的时候,一同带上CF标志位上的进位值进行计算。
assume cs:code,ds:data,ss:stack
data segment
dw 256 dup (0H)
data ends
stack segment
dw 256 dup (0H)
stack ends
code segment
start:
mov ax,0037H
mov bx,0000H ;00370000H
mov cx,0030H
mov dx,0001H ;00300001H
sub,bx,dx
sbb,ax,cx ;注意先从低位数做减法,后做高位数减法.
mov ax,4c00H
int 21H
code ends
end start
12. CMP指令(比较指令,自己理解为if语句里做等号不等号判断)
CMP指令:比较指令。
作用:计算减法功能,但并不保存结果,仅仅根据计算结果影响标志寄存器的位。
CMP指令比较对照(CMP A,B):
ZF=1 A=B(等于)
ZF=0 A!=B(不等于)
CF=1 A<B(小于)
CF=0 A>=B(大于或等于)
CF=0并且ZF=0 A>B(大于)
CF=1或者ZF=1 A<=B(小于或等于)
13. 条件转移指令(if条件转移)
条件转移指令:根据条件是否满足,来决定是否修改IP。
条件转移指令对照(CMP A,B):
ZF=1 A=B(等于) JE
ZF=0 A!=B(不等于) JNE
CF=1 A<B(小于) JB
CF=0 A>=B(大于或等于) JNB
CF=0并且ZF=0 A>B(大于) JA
CF=1或者ZF=1 A<=B(小于或等于) JNA
assume cs:code,ds:data,ss:stack
data segment
dw 256 dup (0H)
data ends
stack segment
dw 256 dup (0H)
stack ends
code segment
start:
mov ax,0011H
mov bx,0011H
cmp ax,bx
je s ;举例ZF=1 A=B JE
mov ax,bx
mov ax,bx
s:
mov bx,cx
mov bx,cx
mov ax,4c00H
int 21H
code ends
end start
14. movsb、movsw(串传送指令)
movsb指令(1个字节)
功能:将ds:si指向的内存单元中的字节传送入es:di指向的内存单元,然后根据DF标志位的值,将si、di递增1或递减1。
movsw指令(2个字节)
功能:将ds:si指向的内存单元中的字传送入es:di指向的内存单元,然后根据DF标志位的值,将si、di递增2或递减2。
15. rep指令 (重复前缀指令,一种循环的方式)
REP 重复前缀指令
作用:根据CX的值,重复执行后面的串传送指令。
;从前向后依次复制粘贴,递增
assume cs:code,ds:data,ss:stack
data segment
db 'china os'
db 8 dup (0H)
data ends
stack segment
dw 256 dup (0H)
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0H
mov es,ax
mov di,8H
cld ;设置DF值为0
mov cx,8H ;循环8次
rep movsb ;重复cx的次数
; movsb ;依次将ds寄存器数据偏移赋值到8-16,标志位递增,0赋值8
; movsb ;1赋值9
; movsb ;2赋值A
; movsb
; movsb
; movsb
; movsb
; movsb
mov ax,4c00H
int 21H
code ends
end start
16. INT 指令(强制触发中断,结束中断 int 21H)
作用:触发中断过程。
语法:INT 中断类型码
assume cs:code,ds:data,ss:stack
data segment
dw 256 dup (0H)
data ends
stack segment
dw 256 dup (0H)
stack ends
code segment
start:
mov ax,1000H
int 0 ;除法溢出中断
mov ax,4c00H
int 21H
code ends
end start
17. 与比较(and)
实例:
test al,al
18. 取ebx补码
实例:
neg ebx