實驗考試題目抽到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挽救回絕殺的騷操作,
在考試結束后做出以下總結:安心復習,不要覺得啥都簡單啥都會!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/241475.html
標籤:其他
下一篇:個人關于學習的一些總結
