题目描述:有一个首地址为mem的100个字的数组,试编制程序删除数组中所有为零的项,并将后续项向前压缩,最后将数组的剩余部分补上零。
这是一道汇编语言关于程序分支结构设计的题目,其实很简单。如果用C语言写很快就可以完成,但由于是初学汇编,所以还是遇到了很多的麻烦。
开始我的算法思想是这样的:用两个指针si、di指着第一个元素,一起向后移动,遇到0的时候跳到移动模块,将si所指向的后面元素全部往前移动。di保存着当前的位置。
开始时是将末位人为置为0,那么向前移动是就可以将后面的元素覆盖为0,但是出现了死循环。经过debug一步一步看看,发现了问题。就是到后面元素全部为0的时候di不能往后移动到结束,一直处于把0往前移动。
想的时候竟然没有考虑到这个问题真是不该,还浪费了很多时间调试。后来不采用末位置0的方法。而是使用result变量记录非0元素个数。完成0元素删除后再根据 result后面的元素置为0。
代码如下:
DATAS SEGMENT data dw 1,0,1,2,0,0,1,9,2,3 ;十个作为测试 ;dw 0,9,8,7,6,5,4,3,2,1 ;dw 0,9,8,7,6,5,4,3,2,1 ; dw 0,9,8,7,6,5,4,3,2,1 ;dw 0,9,8,7,6,5,4,3,2,1 ; dw 0,9,8,7,6,5,4,3,2,1 ;dw 0,9,8,7,6,5,4,3,2,1 ; dw 0,9,2,7,6,5,4,3,2,1 ;dw 0,9,8,7,6,5,4,2,2,1 ; dw 0,9,8,7,6,5,4,3,2,1 result dw 0 ;此处输入数据段代码 DATAS ENDS STACKS SEGMENT ;此处输入堆栈段代码 STACKS ENDS CODES SEGMENT ASSUME CS:CODES,DS:DATAS,SS:STACKS START: MOV AX,DATAS MOV DS,AX mov si,0 mov cx,10 s: cmp cx,0 jz s3 dec cx cmp data[si],0 jz s2 add si,2 jmp s s2: inc result add si,2 jmp s s3: mov ax,10 sub ax,result mov result,ax mov di,0 sub di,2 s0: add di,2 cmp di,20 ja quit mov si,di cmp data[si],0 jz move jmp s0 move: cmp si,20 jb move1 sub di,2 jmp s0 move1: mov ax,data[si+2] mov data[si],ax add si,2 jmp move quit: mov ax,result mov bx,02 mul bx mov si,ax L: cmp si,22 jb add0 jmp next add0: mov data[si],0 inc si jmp L next: mov si,0 sub si,2 output: add si,2 cmp si,20 jb s1 jmp over s1: mov ax,data[si] add ax,30h mov dx,ax mov ah,02h int 21h mov dl,' ' mov ah,02h int 21h jmp output over: MOV AH,4CH INT 21H CODES ENDS END START
代码看起来很乱,很多跳转,但是可以看到思路还是清晰的。
在后面学习笔记(7)中做了改进。