指令包括 JMP,JCC,JCXZ,LOOP,LOOPZ,LOOPNZ,LOOPNE,CALL,RET,INT
目录
无条件转移指令JMP
条件转移指令JCC
计数器CX为0跳转指令 JCXZ
循环指令LOOP,LOOPZ,LOOPNZ,LOOPNE
子程序跳转指令 CALL
子程序返回指令RET
中断指令INT
作用:跳转到对应的指令地址
;使用格式
jmp label ;IP<-IP+位移量
jmp reg/mem ;IP<-reg/mem reg以及mem都需要是16位
jmp far ptr label ;CS=label的段地址,IP=label的偏移地址
jmp far ptr mem ;CS=[mem+2],IP=[mem]
示例:
label:
...
jmp label
;此时往上跳,则位移量为负数
mov ax,4
jmp ax ;ip<-4
;-------------
mov word ptr [bx],0
mov word ptr [bx+2],1500
jmp far ptr [bx] ;CS = 1500 , IP = 0
当指令只需要在当前代码段范围转移时(+-32KB),不需要更改CS地址,只需要修改IP地址
实际编程时,汇编程序会根据目标地址的距离,自动处理成短转移/近转移/远转移
程序员可用操作符short / near ptr /far ptr强制执行
作用:根据运算结果跳转到对应的指令地址
需要的时候查一下就好,不需要强制记住
JCC 指令 - Sunshine - 博客园 (cnblogs.com)
JCC指令 - 极客编程 - 博客园 (cnblogs.com)
cx寄存器通常在程序中用作计数器,JCXZ指令用来判断计数是否为0
;使用格式
jcxz label ;cx=0 , 发生转移:IP<-IP+8位的位移量
;cx!=0,顺序执行
LOOP label ;cx<-cx-1
;cx!=0,循环到标号label
LOOPZ label ;cx<-cx-1
;cx!=0且ZF=1,循环到标号label
LOOPNZ label ;cx<-cx-1
;CX!=0且ZF=0,循环到标号label
示例:
mov cx,count ;设置循环次数
mov si,offset string
xor bx,bx ;bx清0,用于记录空格数
mov al,20h
again: cmp al,es:[si]
jnz next ;zf=0,非空格,转移
inc bx ;zf=1,是空格,个数加1
next inc si
loop again ;字符个数减1,不为0就继续循环
子程序:子程序是完成特定共功能的一段程序,当主程序(调用程序)需要执行这个功能时,采用CALL调用指令转移到该子程序的起始处执行,当运行完子程序功能后,采用RET返回指令回到主程序继续执行
;使用格式
CALL label
CALL reg/mem ;SP<-SP-2,SS:[SP]<-IP, jmp labelreg/mem
call far ptr label
call ffar ptr mem ;SP<-SP-2,SS:[SP]<-IP
;SP<-SP-2,SS:[SP]
call指令其实是做了两件事,执行到CALL时先将CALL指令的下一条指令的IP入栈,在JMP到指定的函数的地址处
;使用格式
RET(或者RETN) ;无参数段内返回
RET(或者RETN) i16 ;有参数段内返回
RETF ;无参数段间返回
RETF i16 ;有参数段间返回
段内返回时需要出栈 ip<-ss:[sp],sp<-sp-+2
段间返回时需要出栈 ip<-ss:[sp],sp<-sp+2 ; cs<-ss:[sp],sp<-sp+2
带参数则在最后 sp<-sp+i16
注意call far ptr 需要与retf配合使用
作用:改变程序的执行顺序
;使用格式
INT i8 ;8位数据
8086的中断:
8086可以管理256个中断,各种中断用一个向量编号来区别,上述的i8即代表一个中断标号
除法错中断:执行除法指令,结果溢出产生的0号中断
指令中断:执行中断调用指令INT i8产生的i8号中断
断点中断:用于断点调试(INT 3)的3号中断(debug时的每次执行一条语句)
溢出中断:执行溢出中断指令 OF=1 产生的4号中断
单步中断:TF=1在每条指令执行后产生的1号中断