实验考试题目抽到10个无符号数排序(欧,欧!欧!!),
在这里插入图片描述
我:哈哈哈哈哈哈哈哈,1分钟结束战斗!

然而10分钟过去了,旁边两人交卷已走,

老师:你好了吗?
我:我这个还有点问题…
(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
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐