+ -
当前位置:首页 → 问答吧 → 一个关于把数组里的‘0’去掉的汇编程序,不知道哪里出错了

一个关于把数组里的‘0’去掉的汇编程序,不知道哪里出错了

时间:2011-05-26

来源:互联网

编译通过,但运行时貌似陷入了死循环,没有结果。
感谢指导!

;delete the '0' bits.

STA SEGMENT STACK
  DW 100H DUP(?)
TOP LABEL WORD
STA ENDS

DATA SEGMENT
MEM DW 1,0,2,0,3,0,4,0,5,0, 90D DUP(0)
DATA ENDS

CODE SEGMENT
MAIN PROC FAR
  ASSUME CS:CODE,SS:STA,DS:DATA
START:
  MOV AX,STA ;初始化。
  MOV SS,AX
  LEA SP,TOP
  MOV AX,DATA
  MOV DS,AX
  XOR SI,SI
  XOR CX,CX

 L1: CMP MEM[SI],0 ;测试数组里的每个元素。
  JE L2
  CMP SI,99D
  JE L4
  ADD SI,1
  JMP L1
 L2: PUSH SI
  INC CX
 L3: INC SI ;发现‘0’,把后面所有的元素前移一位,把‘0’覆盖。
  MOV AX,MEM[SI]
  MOV MEM[SI-1],AX
  CMP SI,99D
  JNE L3
  POP SI
  INC SI
  JMP L1

  SUB SI,CX
 L4: INC SI ;由于删掉了一些(n个)‘0’,把数组最后的n个位置置‘0’。
  MOV MEM[SI],0
  CMP SI,99D
  JNE L4 

  MOV CL,100D
 L5: LEA SI,MEM ;输出数组所有元素。
  MOV DL,[SI]
  ADD DL,30H
  MOV AH,02H
  INT 21H
  ADD SI,2
  DEC CL
  CMP CL,0
  JNE L5

MOV AH,4CH ;结束程序。
INT 21H
MAIN ENDP
CODE ENDS
  END START

作者: engrossment   发布时间: 2011-05-26

1、标号L5所在的位置错了,应标在下一行代码。当然这个问题不是造成死循环的原因。只是使得重复输出MEM的首字符,而不是你要的整个MEN字符串。
2、POP SI之后的INC SI需要删掉,这是逻辑错误,既然你都把后面所有的元素前移了一位,已经相当于SI指向了后一个字符。
3、标号L1之后的四句代码需要调换下顺序,应该先判断SI有没有超值。因为MEM后头都是0,显然这个判断语句一直未能执行。
4、需要借助CX跳出循环。你的CX是用来计数0的个数,所以它不会大于99。
5、根据楼主对MEM的定义(事实上只要保证到MEM[99]=0),标号L4前后的几句代码都是多余的,因为在将后面的元素前移时已经把MEM字符串从后往前逐一置0。

代码修改了下,
;delete the '0' bits.

STA SEGMENT STACK
  DW 100H DUP(?)
TOP LABEL WORD
STA ENDS

DATA SEGMENT
MEM DW 1,0,2,0,3,0,4,0,5,0, 90D DUP(0)
DATA ENDS

CODE SEGMENT
MAIN PROC FAR
  ASSUME CS:CODE,SS:STA,DS:DATA
START:
  MOV AX,STA ;初始化。
  MOV SS,AX
  LEA SP,TOP
  MOV AX,DATA
  MOV DS,AX
  XOR SI,SI
  XOR CX,CX

 L1:CMP SI,99D
JE L4
CMP MEM[SI],0 ;测试数组里的每个元素。
  JE L2 ;问题3,调换了下顺序  
  ADD SI,1
  JMP L1
 L2: PUSH SI
  INC CX
  cmp cx,99
ja l4 ;问题4,增加一个判断语句用于跳出循环 L3: INC SI ;发现‘0’,把后面所有的元素前移一位,把‘0’覆盖。
  MOV AX,MEM[SI]
  MOV MEM[SI-1],AX
  CMP SI,99D
  JNE L3
  POP SI
 ; INC SI 问题2,不需要自增。  
  JMP L1

;**********************
;以下这部分多余,L4定义到后面去
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; SUB SI,CX
; L4: INC SI ;由于删掉了一些(n个)‘0’,把数组最后的n个位置置‘0’。
; MOV MEM[SI],0
; CMP SI,99D
; JNE L4  
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;**********************

L4:MOV CL,100D ;问题5,新标的L4 LEA SI,MEM ;输出数组所有元素。
L5:MOV DL,[SI] ;问题1,L5标到这里 ADD DL,30H
  MOV AH,02H
  INT 21H
  ADD SI,2
  DEC CL
  CMP CL,0
  JNE L5

MOV AH,4CH ;结束程序。
INT 21H
MAIN ENDP
CODE ENDS
  END START

作者: simajian_gg   发布时间: 2011-05-26

排版没弄好
;delete the '0' bits.

STA SEGMENT STACK
  DW 100H DUP(?)
TOP LABEL WORD
STA ENDS

DATA SEGMENT
MEM DW 1,0,2,0,3,0,4,0,5,0, 90D DUP(0)
DATA ENDS

CODE SEGMENT
MAIN PROC FAR
  ASSUME CS:CODE,SS:STA,DS:DATA
START:
  MOV AX,STA ;初始化。
  MOV SS,AX
  LEA SP,TOP
  MOV AX,DATA
  MOV DS,AX
  XOR SI,SI
  XOR CX,CX

 L1:CMP SI,99D
JE L4
CMP MEM[SI],0 ;测试数组里的每个元素。
  JE L2 ;问题3,调换了下顺序  
  ADD SI,1
  JMP L1
 L2: PUSH SI
  INC CX
  cmp cx,99
ja l4 ;问题4,增加一个判断语句用于跳出循环 
L3: INC SI ;发现‘0’,把后面所有的元素前移一位,把‘0’覆盖。
  MOV AX,MEM[SI]
  MOV MEM[SI-1],AX
  CMP SI,99D
  JNE L3
  POP SI
 ; INC SI 问题2,不需要自增。  
  JMP L1

;**********************
;以下这部分多余,L4定义到后面去
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; SUB SI,CX
; L4: INC SI ;由于删掉了一些(n个)‘0’,把数组最后的n个位置置‘0’。
; MOV MEM[SI],0
; CMP SI,99D
; JNE L4  
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;**********************

L4:MOV CL,100D ;问题5,新标的L4  
  LEA SI,MEM ;输出数组所有元素。
L5:MOV DL,[SI] ;问题1,L5标到这里  
  ADD DL,30H
  MOV AH,02H
  INT 21H
  ADD SI,2
  DEC CL
  CMP CL,0
  JNE L5

MOV AH,4CH ;结束程序。
INT 21H
MAIN ENDP
CODE ENDS
  END START

作者: simajian_gg   发布时间: 2011-05-26