; Masm 5.0, Win98
;输入两个多项式,然后将多项式相加结果显示出来.(用了static array 技术)
Poly.asm
MAXLEN = 16
ELEM STRUC
INDEX DW 0
BASE DW 0
NEXT DW 0
ELEM ENDS
DSEG SEGMENT PARA PUBLIC 'DATA'
MSG1 DB 'Create list HA ',0DH,0AH,24H
MSG2 DB 'Create list HB ',0DH,0AH,24H
MSG3 DB 'HA = $'
MSG4 DB 'HB = $'
MSG5 DB 'Input ne : $'
MSG6 DB 'Input nf : $'
MSG7 DB 'HC = $'
MSG8 DB 'Continue(Y/N)$'
INBUF DB MAXLEN,?,MAXLEN DUP (0)
OUTBUF DB MAXLEN DUP (?)
LISTA DW 0
LISTB DW 0
LISTC DW 0
VAL16 DW 10000
DW 1000
DW 100
DW 10
DW 1
HA ELEM 30 DUP (<>)
HB ELEM 15 DUP (<>)
DSEG ENDS
PUBLIC POLY
CSEG SEGMENT PUBLIC 'CODE'
ASSUME CS:CSEG,DS:DSEG,ES:DSEG
POLY PROC FAR
START: MOV AX,DSEG
MOV DS,AX
;
MOV DX,OFFSET MSG1
CALL DISPMSG
MOV BX,OFFSET HA
CALL CREATE
MOV LISTA,BX ;CREATE HA
CALL NEWL
;
MOV DX,OFFSET MSG2
CALL DISPMSG
MOV BX,OFFSET HB
CALL CREATE
MOV LISTB,BX ;CREATE HB
CALL NEWL
;
MOV DX,OFFSET MSG3
CALL DISPMSG
MOV BX,LISTA
CALL SHOWL
CALL NEWL ;DISPLAY THE HA
;
MOV DX,OFFSET MSG4
CALL DISPMSG
MOV BX,LISTB
CALL SHOWL
CALL NEWL ;DISPLAY THE HB
;
;Create the HC = HA+HB
MOV AX,DS
MOV ES,AX
MOV BX,LISTA
MOV DI,OFFSET HA+15*6 ;OFFSET SPACE
MOV SI,LISTB
ADDHB: MOV AX,[SI].INDEX
MOV [DI].INDEX,AX
MOV AX,[SI].BASE
MOV [DI].BASE,AX
CALL ADDITEM
MOV SI,[SI].NEXT
CMP SI,0
JZ HBOVER
ADD DI,6
JMP ADDHB
HBOVER:
MOV DX,OFFSET MSG7
CALL DISPMSG
CALL SHOWL
CALL NEWL ;DISPMSG THE HC
;
CALL NEWL
RET
POLY ENDP
;------------------------------------
;OUTPUT = AX
GETNUM PROC
PUSH DX
PUSH BX
MOV DX,OFFSET INBUF
MOV AH,0AH
INT 21H
MOV BX,OFFSET INBUF+1
CALL ID2B
POP BX
POP DX
RET
GETNUM ENDP
;-----------------------------------
;PROC: ADDITEM: add a element into the list
;INPUT = BX(HEAD),DI(NEWITEM)
;OUTPUT = BX(HEAD)
ADDITEM PROC
PUSH BP
PUSH SI
PUSH DI
MOV SI,BX ;WORKPTR=HEAD FRONT=HEAD
MOV BP,BX
;(WORKPTR->INDEX > NEWITEM->INDEX && WROKPTR!=0)
MOV AX,[DI].INDEX
FIND1:
CMP [SI].INDEX,AX ;WORKPTR->INDEX>NEWITEM->INDEX
JG CONT1
JMP DONE1
CONT1:OR SI,SI
JNE CONT2
JMP USUAL
CONT2:MOV BP,SI ;BP=FRONT (NODE*)
MOV SI,[SI].NEXT
JMP FIND1
DONE1:
CMP [SI].INDEX,AX
JNE INDEXNE
MOV AX,[DI].BASE
ADD [SI].BASE,AX
JMP ADDOK
INDEXNE:CMP SI,BX
JZ ISHEAD
JMP USUAL
ISHEAD:MOV [DI].NEXT,BX ;NEWTIME->NEXT=HEAD
MOV BX,DI ;HEAD=NEWITEM
JMP ADDOK
USUAL: MOV [DI].NEXT,SI ;NEWITME-NEXT=WORKPTR
MOV DS:[BP].NEXT,DI ;FRONT->NEXT =NEWITEM
ADDOK: POP DI
POP SI
POP BP
RET
ADDITEM ENDP
;--------------------------------------
;INPUT = BX
;OUTPUT = BP (1=NULL,0!=NULL)
CREATE PROC
PUSH DX
PUSH CX;
MOV DI,BX
MOV DX,OFFSET MSG5
CALL DISPMSG
CALL GETNUM
CALL NEWL
MOV CX,AX
MOV DX,OFFSET MSG6
CALL DISPMSG
CALL GETNUM
CALL NEWL ;FIRST INDEX = 0?
OR CX,CX
JNZ FIRSTN0
OR AX,AX ;FIRST BASE = 0?
JNZ FIRSTN0
JMP OVER1
FIRSTN0:MOV [DI].INDEX,CX
MOV [DI].BASE,AX
MOV [DI].NEXT,0
ADD DI,6
CONGET:
MOV DX,OFFSET MSG5
CALL DISPMSG
CALL GETNUM
CALL NEWL
MOV CX,AX
MOV DX,OFFSET MSG6
CALL DISPMSG
CALL GETNUM
CALL NEWL
OR CX,CX
JNZ ITEMN0
OR AX,AX
JZ OVER1
ITEMN0: MOV [DI].INDEX,CX
MOV [DI].BASE,AX
CALL ADDITEM
ADD DI,6
JMP CONGET
OVER1:POP CX
POP DX
RET
CREATE ENDP
;-------------------------------------
;OUTPUT = AX
SHOWNUM PROC
PUSH BX
OR AX,AX
JE AX0
MOV BX,OFFSET OUTBUF
CALL IB2A
MOV DX,BX
CALL DISPMSG
JMP SHOWOK
AX0: MOV DL,'0'
CALL ECHO
SHOWOK:POP BX
RET
SHOWNUM ENDP
;-------------------------------------
;OUTPUT = BX(HEAD)
SHOWL PROC
PUSH SI
PUSH DI
;NULL HANDLING
CMP [BX].INDEX,0
JNE DOSHOW
CMP [BX].BASE,0
JNE DOSHOW
MOV DL,'0'
CALL ECHO
JMP OVER2
DOSHOW: MOV SI,BX
CONSHOW:CMP SI,0
JZ OVER2
MOV AX,[SI].BASE
CALL SHOWNUM
MOV DL,'X'
CALL ECHO
MOV DL,'^'
CALL ECHO
MOV AX,[SI].INDEX
CALL SHOWNUM
CMP [SI].NEXT,0
JZ NOTPOS
MOV DI,[SI].NEXT
CMP [DI].BASE,0
JL NOTPOS
MOV DL,'+'
CALL ECHO
NOTPOS: MOV SI,[SI].NEXT
JMP CONSHOW
OVER2:
POP DI
POP SI
RET
SHOWL ENDP
;-------------------------------------
;PROC: ID2B
;INPUT = DS:BX
;OUTPUT = AX
ID2B PROC
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
XOR DI,DI
CMP BYTE PTR [BX+1],'-'
JZ IS_S
JMP NOT_S
IS_S: MOV DI,1 ;FLAG
MOV CL,BYTE PTR [BX]
DEC CL
INC BX
MOV BYTE PTR [BX],CL
NOT_S:
MOV CL,BYTE PTR [BX]
INC BX
XOR CH,CH
MOV SI,OFFSET VAL16
MOV AX,5
SUB AX,CX
ADD AX,AX
ADD SI,AX ;SI POINT TO THE 'EA'
XOR AX,AX
LOOPER1:MOV CL,BYTE PTR [BX]
XOR CH,CH
INC BX
SUB CX,30H
JCXZ NEXT1
;
LAB1:ADD AX,[SI]
LOOP LAB1
NEXT1:ADD SI,2
CMP SI,OFFSET VAL16 + 8
JBE LOOPER1
CMP DI,1
JZ IS_S2
JMP OK
IS_S2:NEG AX
OK:
POP SI
POP DI
POP DX
POP CX
POP BX
RET
ID2B ENDP
;----------------------------------
;PROC: IB2A
;INPUT = (AX),DS:BX(BUFHEAD)
;OUTPUT = DS:BX
IB2A PROC
PUSH AX
PUSH CX
PUSH DX
PUSH SI
INC BX
XOR CX,CX
TEST AH,80H
JS IS_S3
JMP NOT_S3
IS_S3:
MOV CX,1
NEG AX
NOT_S3:
PUSH CX
XOR DI,DI
MOV SI,OFFSET VAL16
LAB3: XOR CL,CL
LAB2: SUB AX,[SI]
INC CL
JC BELOW1
JMP LAB2
BELOW1:
ADD CL,2FH
MOV BYTE PTR [BX][DI],CL
INC DI
ADD AX,[SI]
ADD SI,2
CMP SI,OFFSET VAL16 + 8
JBE LAB3
MOV BYTE PTR [BX+5],'$'
CALL CUT0
;----------------------
POP CX
CMP CX,1 ;'-'?
JZ IS_S4
JMP NOT_S4
IS_S4:DEC BX
MOV BYTE PTR [BX],'-'
NOT_S4:
POP SI
POP DX
POP CX
POP AX
RET
IB2A ENDP
;--------------------------------
;PROC: DISPMSG: print a string in the console
DISPMSG PROC
PUSH AX
MOV AH,9
INT 21H
POP AX
RET
DISPMSG ENDP
;---------------------------------
;PORC: NEWL: print a Line-Feed
NEWL PROC
PUSH AX
PUSH DX
MOV DL,0DH
MOV AH,2
INT 21H
MOV DL,0AH
MOV AH,2
INT 21H
POP DX
POP AX
RET
NEWL ENDP
;--------------------------------
;PROC:CUT0
;INPUT = DS:BX(NUMSTR HEAD)
;OUTPUT = CUT THE '0'S IN THE FRONT
CUT0 PROC
PUSH AX
LAB: MOV AL,[BX]
CMP AL,30H
JZ GOON1
JMP OK2
GOON1: INC BX
JMP LAB
OK2: POP AX
RET
CUT0 ENDP
;--------------------------
;PROC: ECHO: print a character in the console
ECHO PROC
PUSH AX
MOV AH,2
INT 21H
POP AX
RET
ECHO ENDP
;---------------------------
CSEG ENDS
END