荣誉值:0
信誉值:0
注册日期:2009-02-21 16:37 |
第八章实验7,我写了三个程序,其中一个编译链接正确,另外两个说是除法溢出,大家帮忙看一下是怎么了?
下面这一个是我最早写的,我觉得这种算法很笨,思路也很传统:
ASSUME CS:code,DS:data,ES:table
data SEGMENT
DB '1975','1976','1977','1978','1979','1980','1981','1982','1983'
DB '1984','1985','1986','1987','1988','1989','1990','1991','1992'
DB '1993','1994','1995'
DD 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
DD 245980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
DW 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8228
DW 11542,14430,15257,17800
data ENDS
table SEGMENT
DB 21 DUP ('year summ ne ?? ')
table ENDS
code SEGMENT
start: MOV BX,0
MOV BP,0
MOV CX,21
s1:MOV AX,DS:[BX]
MOV ES:[BP],AX
MOV AX,DS:[BX+2]
MOV ES:[BP+2],AX
ADD BX,4
ADD BP,16
LOOP s1
MOV BX,84
MOV BP,5
MOV CX,21
s2:MOV AX,DS:[BX]
MOV ES:[BP],AX
MOV AX,DS:[BX+2]
MOV ES:[BP+2],AX
ADD BP,16
ADD BX,4
LOOP s2
MOV BX,168
MOV BP,000Ah
MOV CX,21
s3:MOV AX,DS:[BX]
MOV ES:[BP],AX
ADD BX,2
ADD BP,16
LOOP s3
MOV BP,0
MOV CX,21
s4:MOV DX,es:[bp+7]
MOV AX,es:[bp+5]
DIV WORD PTR es:[bp+000ah]
MOV ES:[BP+000dh],AX
ADD BP,16
LOOP s4
MOV AX,4c00h
INT 21h
code ENDS
END start
这个程序直接运行时出现了“NTVDM CPU遇到无效指令。CS:002d,IP:0d26 OP:ff ff a7 00 00 选择“关闭 ”终止应用程序。”的提示,这是怎么了?用debug逐步加载时没有错误,就是在s4这步循环运行时提示说是除法溢出错误,是哪里溢出了呢?商不是在在 AX中,然后赋给ES:[BP+000DH]吗?
第二种方法,这种方法是我见到论坛里有人用栈写,我也用栈写了一个:
ASSUME CS:code,DS:datas,SS:stacks
DATAS SEGMENT
DB '1975', '1976', '1977', '1978', '1979', '1980', '1981', '1982'
DB '1983', '1984', '1985', '1986', '1987', '1988', '1989', '1990'
DB '1991', '1992', '1993', '1994', '1995'
DD 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 97479, 140417, 197514
DD 345980, 590827, 803530, 118300, 184300, 2759000, 3753000, 4649000, 5937000
DW 3, 7, 9, 13, 28, 38, 130, 220, 476, 778, 1001, 1442, 2258, 2793, 4037, 5635, 8226
DW 11542, 14430, 15257, 17800
DATAS ENDS
TABLE SEGMENT
DB 21 DUP ('year summ ne ?? ')
TABLE ENDS
STACKS SEGMENT
DB 16 DUP (0)
STACKS ENDS
code SEGMENT
start: MOV BP,000ah
MOV BX,0
MOV BP,0
MOV CX,21
s:PUSH DS:[BX]
PUSH DS:[BX+2]
PUSH DS:[84+BX]
PUSH DS:[84+BX+2]
PUSH DS:[164+SI]
POP ES:[BP]
POP ES:[BP-4]
POP ES:[BP-2]
POP ES:[BP-4]
POP ES:[BP-2]
MOV DX,ES:[BP+7]
MOV AX,ES:[BP+5]
DIV WORD PTR ES:[BP+000ah]
MOV ES:[BP+000dh],AX
ADD BX,4
ADD SI,2
ADD BP,16
LOOP s
MOV AX,4c00h
INT 21h
code ENDS
END start
这个程序在用debug单步跟踪时到做除法时就出现了“Divide overflow”的错误。
第三种方法:
ASSUME CS:code,DS:data,ES:table
data SEGMENT
DB '1975','1976','1977','1978','1979','1980','1981','1982','1983'
DB '1984','1985','1986','1987','1988','1989','1990','1991','1992'
DB '1993','1994','1995'
DD 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
DD 245980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
DW 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8228
DW 11542,14430,15257,17800
data ENDS
table SEGMENT
DB 21 DUP ('year summ ne ?? ')
table ENDS
code SEGMENT
start: MOV AX,data
MOV DS,AX
MOV BX,0
MOV AX,table
MOV ES,AX
MOV BP,0
MOV SI,0
MOV DI,0
MOV CX,21
s: MOV AX,DS:[BX]
MOV ES:[BP],AX
MOV AX,DS:[BX+2]
MOV ES:[BP+2],AX
MOV AX,DS:[BX+84]
MOV ES:[BP+5],AX
MOV AX,DS:[BX+2+84]
MOV ES:[BP+7],AX
MOV AX,DS:[SI+168]
MOV ES:[BP+000ah],AX
MOV DX,ES:[BP+7]
MOV AX,ES:[BP+5]
DIV WORD PTR ES:[BP+000ah]
MOV ES:[000dh+BP],AX
ADD BX,4
ADD SI,2
ADD DI,2
ADD BP,16
LOOP s
MOV AX,4c00h
INT 21h
code ENDS
END start
这种方法没有错误,运行跟踪结果也正确。
麻烦看到本帖的朋友帮忙分析一下上面的错误,也许只是一些小的错误,但我没看出来,谢谢了!!! | | |