DOS汇编练习(12)——总结~
实验考试题目抽到10个无符号数排序(欧,欧!欧!!),我:哈哈哈哈哈哈哈哈,1分钟结束战斗!然而10分钟过去了,旁边两人交卷已走,老师:你好了吗?我:我这个还有点问题…(woc心态崩了呀…)怎么虚拟机弹窗内存错误!??到底咋回事啊,debug -p快执行100遍了,-t要执行1000遍了怎么还是不行,-g直接没了是啥玩意啊!!!?edit 调出来重写了两个asm文档;不行这个机子用edit有点慢,
实验考试题目抽到10个无符号数排序(欧,欧!欧!!),
我:哈哈哈哈哈哈哈哈,1分钟结束战斗!
老师:你好了吗?
我:我这个还有点问题…
(woc心态崩了呀…)
怎么虚拟机弹窗内存错误!??
到底咋回事啊,debug -p快执行100遍了,-t要执行1000遍了怎么还是不行,-g直接没了是啥玩意啊!!!?
edit 调出来重写了两个asm文档;
不行这个机子用edit有点慢,调出记事本重写了两个文档…心态崩了啊不停地敲键盘…
这里用选择排序回忆一遍当时写的无脑Bug:
(注意缩进的那一行PUSH CX)
DATA SEGMENT
VAR DB 12H,43H,34H,2H,200,3FH,3EH,1,120,5EH
VARLEN EQU $-VAR
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX ;导入数据段数据
MOV CX,VARLEN ;装填计数初值
DEC CX ;实际循环次数为N-1次
PUSH CX ;...好大一只Bug你没看见
MOV BX,OFFSET VAR ;取全局变量首地址,即将标号VAR的地址存入BX,MOV BX,0000
;故查看结果时用DDS:0命令
WAI:
MOV SI,BX ;分别存入SI,DI
MOV DI,BX
MOV AL,[BX] ;将初值存入AL
NEI: ;内层循环找出每一趟的最小值
INC SI
CMP AL,[SI]
JBE NEXT ;若(AL)<=[SI],则不交换
MOV AL,[SI] ;否则,将每一趟找到的最小值先放入AL
MOV DI,SI ;SI和DI+1
NEXT:
LOOP NEI
XCHG AL,[BX] ;一趟比较过后,将首址0000中与AL中找到的最小值交换
XCHG AL,[DI] ;,防止排序前第一值被覆盖
INC BX
POP CX
DEC CX
JNZ WAI ;Loop WAI
EXIT:
MOV AH,4CH
INT 21H
CODE ENDS
END START
在-p10,-t10跟踪了将近20分钟后,怎么也检查不出来(紧张啊真的,课下都练了多少遍了排序还不会吗)
总算发现,当执行LOOP WAI的时候直接程序结束自动退出debug(???什么情况,头一回遇到),改成DEC CX,JNZ判断跳转N次后,最终莫名其妙的计数器CX中的值突然从0008H(正常范围内)——变到了>0306H(…woc这什么鬼!?哪来这么大值,等等。。)
造成这个Bug的原因是这样:本应防止外层循环部分控制趟数的PUSH CX指令写在了初始化的START部分,这样就造成了后期正确比较完第一趟冒泡或者选择排序后,一直POP CX,POP CX…
像这样无脑地一直POP CX,程序能对才怪!
。。。哦既然是这样的话我就知道了
教科书般的正确做法:将PUSH CX放入外层循环,每次比较完一趟后再减1,否则会只有POP CX、POP CX…
wai: ;外层循环控制趟数
mov si,bx
mov di,bx
inc si
push cx ;这句的位置及其关键!不要不理解而放在了循环外面,否则会造成程序死循环
那没事了。
一旁的老师:你没装填怎么会有数据的,按两次t,这不就行了,来,这回你的好了吗?
我:来!
先-q
cls
再-p2(吼吼吼,我就不两次t了以卑微地表示用得比较熟练)
再dds:0
我:老师你看数据段一开始乱序
老师:嗯
再:来!-g
dds:0
老师:好了,关了吧。
从上机课上听不懂汇编指令用法、算法逻辑的小白
到期末实验考试上来给自己写了个死循环,哗哗哗现场Debug挽救回绝杀的骚操作,
在考试结束后做出以下总结:安心复习,不要觉得啥都简单啥都会!
冒泡法正确示例:
DATA SEGMENT
DAT1 DB 08H,04H,09H,01H,60H,02H
LEN1 = $-DAT1
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
MOV CX,LEN1
DEC CX
WAI: ;外层循环控制趟数
PUSH CX ;注意每次必须在外层循环内PUSH CX
LEA SI,DAT1
NEI: ;内存循环控制比较次数
MOV AL,[SI]
INC SI ;相邻作比较
MOV BL,[SI]
CMP AL,BL
JBE NEXT ;从小到大排序,如果AL<BL则跳过,比较下一个相邻值
XCHG AL,BL
MOV BYTE PTR [SI],BL ;送回原来的地址
MOV BYTE PTR [SI-1],AL
NEXT:
;注意千万不能在这里加INC SI,否则SI每比较完一次多加一次
LOOP NEI ;CX-1
POP CX ;比较完一趟弹出CX原来的值
LOOP WAI ;CX-1
MOV AH,4CH
INT 21H
CODE ENDS
END START
更多推荐
所有评论(0)