汇编太难了(1)——删除数组元素

在附加段中,有一个首地址为LIST和未经排序的字数组,在数组的第一个字中,存放着该数组的长度,数组的首地址已存放在DI寄存器中,AX寄存器中存放着一个数。要求编制一程序,在数组中查找该数,如果找到了此数,则把它从数组中删除。

DATAS SEGMENT
  	LIST DW 10,45h,345h,45h,189h,21h,2345h,5678h,100h,200h,189h
  	ADDR1 DW 89H
DATAS ENDS

STACKS SEGMENT
	DB  200  dup(?)
	TOP LABEL WORD
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,ES:DATAS,SS:STACKS
START:
	;将数据段中的数据加载到ES,DS中
    MOV AX,DATAS
    MOV ES,AX
	MOV DS,AX
	MOV DI,OFFSET LIST  ; (di) = 0AH
	MOV AX,ADDR1  		;(ax) = 89H
	CLD  				;(di)向前移动
	PUSH DI   			; di 进栈,保存数组大小值
	MOV CX,ES:[DI]      ;cx表示要移动的次数
	ADD DI,2  			; 指向数组中的第一个元素
	REPNE  SCASW  		;串扫描,当di指定的值跟ax中的值相等时,ZF=1,即满足JE/JZ
	JE DELETE 
	POP DI
	JMP SHORT EXIT	
DELETE: 
	JCXZ DEC_CNT 		;如果cx=0 ,即改动数组大小即可
NEXT_EL:            	;cx是多少就移动多少次
	MOV BX,ES:[DI]  	;因为di是指向匹配的下一个,所以直接将di覆盖di-2
	MOV ES:[DI-2],BX 
	ADD DI,2 			;没完就继续
	LOOP NEXT_EL
DEC_CNT:
	POP DI
	DEC WORD PTR ES:[DI]
EXIT: 
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START


MOV AX,DATAS
MOV DS,AX
MOV ES,AX
这三个的作用:把附加段中的数据移动到DS寄存器和ES寄存器中,因为无法直接从内存移到DS,所以借用AX

REPNE SCASW
REPNE:不相等/不为0则重复
SCASW:是 SCAS 串扫描的扩展,SCASB 字节,SCASW 字,SCASD 双字
SCASB: (AL)-((Desination-index)),(Destination-index) <- (Destination - index) ± 1
SCASW: (AX)-((Desination-index)),(Destination-index) <- (Destination - index) ± 2
SCASD: (EAX)-((Desination-index)),(Destination-index) <- (Destination - index) ± 4
注意: 当使用REPNE SCASW时,如果匹配到了的话,DI是指向匹配到的下一个字,CX是剩余的字的数量。

JCXZ: jump if cx equals zero.

你可能感兴趣的:(汇编语言)