2 sinat 24343049 sinat_24343049 于 2016.04.28 22:23 提问

汇编语言屏幕总是闪烁

新手一枚正在学习汇编
输出的时候屏幕总是闪烁(屏幕操作位置不是特别懂)
另外这个程序的逻辑问题还有一些问题,望大神指教

DATA SEGMENT
SHOW1 DB ' +--------------------------------------------------------------------------+',0DH,0AH,'$'
SHOW2 DB ' | 1.INPUT NUMBER |',0DH,0AH,'$'
SHOW3 DB ' | 2.2->10 NUMBER |',0DH,0AH,'$'
SHOW4 DB ' | 3.COMPOSITOR NUMBER |',0DH,0AH,'$'
SHOW5 DB ' | 4.MAX NUMBER |',0DH,0AH,'$'
SHOW6 DB ' | 5.EXIT PROGRAM |',0DH,0AH,'$'
SHOW7 DB ' +--------------------------------------------------------------------------+',0DH,0AH,'$'
SHOW8 DB 0DH,0AH,'THE ','$'
SHOW9 DB ' NUMBER IS :','$'
SHOW10 DB 0DH,0AH,'$'
SHOW11 DB 'MAX IS :','$'
ILLEGAL DB 0DH,0AH,'Illegal character. Try again : $'
NUM DW 10 DUP(0)

NUM2 DW 0
MAX DW ?
FLAG DB 0
SIGN1 DB ' '
SIGN2 DB '-'
SIGN DB 30H
LINE DB 7

ROW DB 0
DATA ENDS

SHOW_MENU MACRO SHOW

LEA DX,SHOW

MOV AH,09H
INT 21H
ENDM

stack segment
stt dw 50 dup(?)
stack ends

CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
MOV AX,DATA
MOV DS,AX

CALL  SCREEN

MOV   AL,0      ;初始化
MOV   BH,11110000B
MOV   CH,7
MOV   CL,0
MOV   DH,19H        ;16ln
MOV   DL,4FH        ;80col
MOV   AH,06H
INT   10H

MOV   BH,0      
MOV   DH,7      ;光标第七行
MOV   DL,0
MOV   AH,02H
INT   10H

C0: MOV CX,2
MOV AH,01H
INT 21H
CMP AL,'1'
JNZ C1

C1 :

CMP AL,'2'
JNZ C2
CALL OUTPUT_BY_10
MOV BL,7
CMP BL,18H
JZ C2
INC LINE

C2:
CMP AL,'3'
JNZ C3
CALL campare
MOV BL,7
CMP BL,18H
JZ C3
INC LINE

C3:
CMP AL,'4'
JNZ C4
CALL PRO4
MOV BL,LINE
CMP BL,18H
JZ C4
INC LINE

C4:
CMP AL,'5'
JMP EXIT0
EXIT0:
MOV AH,4CH
INT 21H

;/**************************************************************************/

input proc

push ax
push bx
push cx
push dx

MOV CX,10

PUTNUM:
JMP @READ ;

@ERROR: ;
LEA DX, ILLEGAL ; load and display the string ILLEGAL
MOV AH, 9

INT 21H

@READ: ;
XOR BX, BX ; 清空 BX
XOR CX, CX ; 清空 CX

MOV AH, 1 ;
INT 21H ;

CMP AL, "-" ; compare AL with "-"
JE @MINUS ; jump to label @MINUS if AL="-"

CMP AL, "+" ; compare AL with "+"
JE @PLUS ; jump to label @PLUS if AL="+"
JMP @INPUT ; jump to label @INPUT

@MINUS: ;
MOV CX, 1 ; set CX=1

@PLUS: ;
INT 21H ; read a character
CMP AL, 0DH ; compare AL with CR
JE @END ; jump to label @END if AL=CR

@INPUT: ;
CMP AL, 30H ; compare AL with 0
JL @ERROR ; jump to label @ERROR if AL<0

 CMP AL, 39H                  ; compare AL with 9
 JG @ERROR                    ; jump to label @ERROR if AL>9

 AND AX, 000FH                ; convert ascii to decimal code

 PUSH AX                      ; push AX onto the STACK

 MOV AX, 10                   ; set AX=10
 MUL BX                       ; set AX=AX*BX
 MOV BX, AX                   ; set BX=AX

 POP AX                       ; pop a value from STACK into AX

 ADD BX, AX                   ; set BX=AX+BX

 MOV AH, 1                    ; set input function
 INT 21H                      ; read a character

 CMP AL, 0DH                  ; compare AL with CR
 JNE @INPUT                   ; jump to label if AL!=CR

@END: ;

OR CX, CX ; check CX is 0 or not
JE @EXIT ; jump to label @EXIT if CX=0
NEG BX ; negate BX
MOV SI,0
MOV BX,NUM[SI]
ADD SI,2

LOOP PUTNUM

@EXIT: ;
CALL SCREEN
pop dx
pop cx
pop bx
pop ax
RET
input endp

;/**************************************************************************/
output_by_10 proc
push ax
push bx
push cx
push dx

MOV CX,10

OUTPUT:
MOV SI,0
MOV BX,NUM[SI]
PUSH CX

CMP BX, 0                      ; compare BX with 0
JGE @START                     ; jump to label @START if BX>=0
MOV AH, 2                      ; set output function
MOV DL, "-"                    ; set DL='-'
INT 21H                        ; print the character

NEG BX                         ; take 2's complement of BX

@START: ; jump label

MOV AX, BX                     ; set AX=BX
XOR CX, CX                     ; clear CX
MOV BX, 10                     ; set BX=10

@REPEAT:

XOR DX, DX ; clear DX
DIV BX ; divide AX by BX
PUSH DX ; push DX onto the STACK
INC CX ; increment CX
OR AX, AX ; take OR of Ax with AX
JNE @REPEAT ; jump to label @REPEAT if ZF=0

 MOV AH, 2                     ; set output function

@DISPLAY:

POP DX ; pop a value from STACK to DX
OR DL, 30H ; convert decimal to ascii code
INT 21H ; print a character
LOOP @DISPLAY ; jump to label @DISPLAY if CX!=0

 ADD SI,2
 POP CX
 LOOP OUTPUT

 CALL  SCREEN

 pop dx
 pop cx
 pop bx
 pop ax

RET ; return

output_by_10 endp

;/***********************************************************************/
campare PROC NEAR
push ax
push bx
push cx
push dx

LEA   DX,SHOW10
MOV   AH,09H
INT   21H
MOV   BL,LINE
CMP   BL,18H
JZ    LOOP5
INC   LINE

LOOP5:
MOV CX,10
DEC CX
AGAIN:
MOV SI,0
PUSH CX
NEXT9:
MOV AX,NUM[SI]
MOV BX,NUM[SI+2]
CMP AX,BX
JS NEXT10
XCHG AX,BX
MOV NUM[SI],AX
MOV NUM[SI+2],BX
NEXT10:
ADD SI,2
LOOP NEXT9

POP   CX
LOOP  AGAIN
CALL  OUTPUT_BY_10
LEA   DX,SHOW10
MOV   AH,09H
INT 21H 
MOV   BL,LINE
CMP   BL,18H
JZ    LOOP6
INC   LINE

LOOP6:
CALL SCREEN

pop dx
 pop cx
 pop bx
 pop ax
RET 

campare ENDP

;/*****************************************************************************/

PRO4 PROC NEAR
push ax
push bx
push cx
push dx

LEA   DX,SHOW10
MOV   AH,09H
INT   21H   
MOV   BL,LINE
CMP   BL,18H
JZ    LOOP3
INC   LINE

LOOP3:
LEA DX,SHOW11
MOV AH,09H
INT 21H
MOV CX,0AH
MOV SI,0
MOV AX,NUM[SI]
MOV MAX,AX
NEXT11:
MOV AX,NUM[SI]
MOV BX,MAX
CMP AX,BX
JS NEXT12
MOV MAX,AX
NEXT12:
ADD SI,2
LOOP NEXT11

MOV   AX,MAX
TEST  AX,8000H
JZ    ABC3
NEG   AX
PUSH  AX
MOV   DL,SIGN2      ;输出负号
MOV   AH,02H
INT   21H
POP   AX

ABC3:
MOV BL,0AH
DIV BL
MOV DL,AH
AND DX,00FFH
PUSH DX
INC NUM2
AND AX,00FFH
CMP AX,0
JNZ ABC3
MOV CX,NUM2
ABC4:
POP DX
ADD DL,30H
MOV AH,02H
INT 21H
LOOP ABC4
MOV NUM2,0
LEA DX,SHOW10
MOV AH,09H
INT 21H
MOV BL,LINE
CMP BL,18H
JZ LOOP4
INC LINE
LOOP4:
CALL SCREEN
pop dx
pop cx
pop bx
pop ax
RET
PRO4 ENDP

;/******************************************INIT SCREEN****************************/
SCREEN PROC NEAR
push ax
push bx
push cx
push dx

MOV   AL,0         
MOV   BH,11110000B
MOV   CH,0
MOV   CL,0
MOV   DH,6      
MOV   DL,4FH    
MOV   AH,06H
INT   10H

MOV   BH,0      
MOV   DH,0      
MOV   DL,0
MOV   AH,02H
INT   10H

SHOW_MENU   SHOW1   
SHOW_MENU   SHOW2
SHOW_MENU   SHOW3
SHOW_MENU   SHOW4
SHOW_MENU   SHOW5
SHOW_MENU   SHOW6
SHOW_MENU   SHOW7

MOV   BH,0      
MOV   DH,LINE       
MOV   DL,0
MOV   AH,02H
INT   10H

 pop dx
 pop cx
 pop bx
 pop ax
RET

SCREEN ENDP

CODE ENDS
END START

1个回答

BoycoKove
BoycoKove   2016.04.29 00:11

这么多代码,加点注释才会有人看呀

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!