控制转移指令
例
例4.17
在内存的数据段中存放了若干个8位带符号数,数据块的长度为COUNT(不超过255),首地址为TABLE,试统计其中正数、负数及零的个数,并分别将统计结果在
PLUS. MINUS和ZERO单元。
为了统计正数、负数和零的个数,可先将PLUS、MINUS和ZERO三个单元清零,然后将数报表中的带符号数逐个取入AL寄存器并使其影响状态标志位,再利用前而介绍的 JS、JZ 等条件转称指令测试该数是一个负数、零还是正数,然后分别在相应的单元中进行计数。程序如下:
li417.asm
data segment TABLE db 1,2,3,4,5,6,7,8,9 ;9 db -1,-2,-3,-4,-5,-6,-7,-8,-9 ;9 db 0,0,0,0,0,0,0,0,0,0,0 ;11 COUNT equ $-TABLE org 0040H PLUS db ? MINUS db ? ZERO db ? data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax XOR AL,AL ;(AL)<-0 MOV PLUS,AL ;清PLUS单元 MOV MINUS,AL ;清MINUS单元 MOV ZERO,AL ;清ZERO单元 LEA SI,TABLE ;(SI)-数据表首址 MOV CX,COUNT ;(CX)-数据表长度 CLD ;清控制标志位DF CHECK:LODSB ;取一个数据到AL OR AL,AL ;使数据影响状态标志位 JS X1 ;如为负,转X1 JZ X2 ;如果为负,转X2 INC PLUS ;否则为正,PLUS单元加1 JMP NEXT X1: INC MINUS ;MINUS单元加1 JMP NEXT X2: INC ZERO ;ZERO单元加1 NEXT:LOOP CHECK ;CX减1,如不为零,则转CHECK mov ah,4ch int 21h code ends end start
运行结果
以上程序中的LOOP CHECK指令是一条循环控制指令,它的操作是将CX寄存器的内 容减1,如结果不等于零,则转移到短标号CHECK。随后将讨论这条指令。
例4.18
在以DATA1为首址的内存数据段中,存放了200个16位带符号数,试将其中最大和最小的带符号数找出来,分别存放到以MAX和MIN为首的内存单元中。
为了寻找最大和最小的元素,可先取出数据块中的一个数据作为标准,暂且将它同时存放到MAX和MIN单元中,然后将数据块中的其他数据逐个分别与MAX和MIN中的数 相比较,凡大于MAX者,取代原来MAX中的内容,凡小于MIN者,取代原来MIN中的 内容,最后即可得到数据块中最大和最小的带符号数。
编程如下: 必须注意,比较带符号数的大小时,应该采用JG和JL等条件转移指令,根据要求可编程如下:
li418.asm
data segment DATA1 dw 1,2,3,4,5,6,7,8,9,32767 ;MAX=7FFF dw -1,-2,-3,-4,-5,-6,-7,-8,-9,-32768 ;MIN=8000 COUNT equ ($-DATA1)/2 org 0040H MAX dw ? MIN dw ? data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax LEA SI, DATA1 ;(SI)<-数据块首址 MOV CX,200 ;(CX)<-数据块长度 CLD ;清方向标志DP LODSW ;取一个16位带符号数到AX MOV MAX,AX ;送MAX单元 MOV MIN,AX ;送MIN单元 DEC CX ;(CX)<-(CX)-1 NEXT: LODSW ;取下一个16位带符号数 CMP AX,MAX ;与MAX单元内容比较 JG GREATER ;大于MAX,则转GREATER CMP AX,MIN ;否则,与MIN单元内容比较 JL LESS ;小于MIN,则转LESS JMP GOON ;否则,转GOON GREATER: MOV MAX,AX ;(MAX)<-(AX) JMP GOON ;转 GOON LESS: MOV MIN,AX ;(MIN)<-(AX) GOON: LOOP NEXT ;CX减1,若不等于零,转NEXT mov ah,4ch int 21h code ends end start
运行结果