9.7jcxz指令
jcxz指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对ip的修改范围都为-128~127
指令格式:jcxz 标号
(如果cx=0,则转移到标号处执行)
jcxz 标号 指令操作:
当cx=0时,ip=ip+2位位移
8位位移=标号处的地址-jcxz指令后的第一个字节的地址。
8位位移的范围为-128~127,用补码表示;
8位位移由编译程序在编译时算出。
当cx≠0时,什么也不做(程序向下执行)
我们从jcxz的功能中可以看出,指令jcxz 标号的功能用c语言写相当于:
if(c==0)
jmp short 标号
9.9 根据位移进行转移的意义
前面我们讲到:
jmp short 标号
jmp near ptr 标号
jcxz 标号
loop 标号
等几种汇编指令,他们对ip的修改是根据转换目的地址和转换起始地址之间的位移来进行的。在他们对应的机器码中不包含转移的目的地址,而包含的是到目的地址的位移。
这种设计,方便了程序段在内存中的浮动装配
例如:
mov cx,6
mov ax,10h
s: add ax,ax
loop s
这段程序装在内存中的不同位置都可正确执行,因为loo s在执行时只涉及s的位移,而不是s的地址。如果loops的机器码中包含的是s的地址,则就对程序段在内存中的偏移地址有了严格的限制,因为机器码中包含的是s的地址,如果s处的指令不在目的地址处,程序的执行就会出错。而loop s的机器码中包含的是转移的位移,就不存在这个问题了,因为,无论s处的指令的实际地址是多少,loop指令的转移位移是不变的。
实验九
assume cs:codesg data segment db 'welcome to masm!' db 00000010b,00100100b,01110001b data ends stack segment dw 10 dup(0) stack ends codesg segment start: mov ax,0b800h mov ds,ax mov ax,data mov es,ax mov ax,stack mov ss,ax mov sp,11 mov bx,7c0h mov si,0 mov di,16 mov cx,3 s0: push cx mov cx,16 s: mov al,es:[si] mov ds:[bx],al mov al,es:[di] mov ds:[bx+1],al add si,1 add bx,2 loop s pop cx mov si,0 inc di add bx,80h loop s0 mov ax,4c00h int 21h codesg ends end start