题目描述:有一个首地址为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)中做了改进。