1. 程式人生 > >80*86組合語言學生成績排序系統

80*86組合語言學生成績排序系統

五、實驗結果及分析

1、實驗執行過程及分析

(1)選單:

主要程式碼:

        在輸出選單之前首先使用清屏效果,以下為清屏效果的原始碼:

MOV AH,15

INT 10H

MOV AH,0

INT 10H

             之後呼叫巨集指令輸出選單,並呼叫選擇輸入子程式:

OUTPUT_AH_9 CATALOG_1  

:

:

OUTPUT_AH_9 CATALOG_6

CALL INPUT_CHOICE   ; 呼叫選擇輸入子程式

             用BUTTON判斷是否需要再次迴圈,比較BUTTON是否為1,如果輸入ESC,則退出選單迴圈結束程式,如果BUTTON為0,則迴圈輸出選單。

CMP BUTTON,1

JNE OUTPUT_CATALOG

 

(2)輸入功能:

主要程式碼:

通過迴圈判斷NAME_BUF[SI+2]中的值是否為回車,若不是,則將該名字傳送到用來儲存資料的空間NAME_GRADE_SAVE中。

LOOP_INPUT_NAME:

MOV AL, NAME_BUF[SI+2]

CMP AL,13

JE INPUT_GRADE

MOV NAME_GRADE_SAVE [DI][BX],AL

INC SI

INC BX

LOOP LOOP_INPUT_NAME

通過迴圈判斷NAME_BUF[SI+2]中的值是否為回車,若不是,則將該成績傳送到用來儲存資料的空間NAME_GRADE_SAVE中。

        LOOP_INPUT_GRADE:

                MOV AL,GRADE_BUF[SI+2]

                CMP AL,13

                JE AGAIN

                MOV NAME_GRADE_SAVE[DI][BX],AL

                INC SI

                INC BX

                LOOP LOOP_INPUT_GRADE

             最後輸出一個值進行判斷,若值為”y”,則迴圈到輸入名字之前再次輸入名字,若值為”n”,則退出該輸入子程式。

         OUTPUT_AH_9 TIP_5

                  MOV AH,1

                  INT 21H

                  CMP AL,"y"

                  JE INPUT

                  CMP AL,"n"

                  JE INPUT_OUT

                  OUTPUT_AH_9 TIP_2

            JMP AGAIN

 

(3)輸出功能:

主要程式碼:

    用2號功能依次迴圈輸出名字,當判斷下一個地址的值為’$’時停止輸出;並在迴圈的同時使變數NAME _LONG的值自加1,以便之後輸出空格。

      LOOP_OUTPUT_NAME:

               MOV AL,NAME_GRADE_SAVE[DI][BX]

               CMP AL,'$'

               JE LOOP_OUTPUT_NAME_END

               MOV DL,AL

               MOV AH,2

               INT 21H

               INC BX

               INC NAME_LONG

               JMP LOOP_OUTPUT_NAME

 

          根據名字的長度確定應該輸出多少個空格,並迴圈輸出空格。

         MOV AL,14

               SUB AL,NAME_LONG

               PUSH CX

               MOV CX,0

               MOV CL,AL

            LOOP_KONGGE_1:

               KONGGE

               LOOP LOOP_KONGGE_1

 

          用2號功能依次迴圈輸出成績的值,當判斷下一個地址的值為’$’時停止輸出;並在迴圈的同時使變數GRADE_LONG的值自加1,以便之後輸出空格。

          LOOP_OUTPUT_GRADE:

               MOV AL,NAME_GRADE_SAVE[DI][BX]

               INC GRADE_LONG

               CMP AL,'$'

               JE LOOP_OUTPUT_GRADE_END

               MOV DL,AL

               MOV AH,2

               INT 21H

               INC BX

               JMP LOOP_OUTPUT_GRADE

 

根據成績的長度確定應該輸出多少個空格,並迴圈輸出空格。

MOV AL,14

               SUB AL,GRADE_LONG

               PUSH CX

               MOV CX,0

               MOV CL,AL

            LOOP_KONGGE_2:

               KONGGE

               LOOP LOOP_KONGGE_2

 

          將變數MINGCI每次迴圈時自加1,並在輸出完名字和成績之後輸出該變數作為名次。

         MOV DL, MINGCI

               MOV AH,2

               INT 21H

               INC MINGCI

(4)排序功能:

主要程式碼:

用迴圈求出每個成績的長度,當執行到’$’時,停止迴圈。

         LOOP_SIZE:

                 INC GRADE_LONG

                 INC SI

                 CMP NAME_GRADE_SAVE[BX][SI],'$'

                  JNE LOOP_SIZE

 

    比較前一個成績和後一個成績,若前一個大於後一個,則跳轉到交換結束(即不交換),若前一個小於後一個,則跳轉到交換的程式。

         MOV AL,GRADE_LONG

                  CMP GRADE_MAX_LONG,AL

                  JA COMPARE_END

JB SORT_SHORT_CHANGE

若輸入的兩個數相等,則依次從高位到低位一個一個進行比較,若前者比後者小,則交換,若後者比前者小,則不交換,若相等,則繼續迴圈。

LOOP_COMPARE:

MOV AL,NAME_GRADE_SAVE[BX][SI]

CMP NAME_GRADE_SAVE[BX][DI],AL

JA COMPARE_END

JB SORT_CHANGE   ;前者比後者小,交換

INC SI

INC DI

CMP NAME_GRADE_SAVE[BX][DI],'$'

JNE LOOP_COMPARE

JMP COMPARE_END

    將SI和DI各減小10,指向名字的第一個位置,迴圈20次,將整個儲存學生名字和成績的單位全部依次交換。

         SUB SI,10

                SUB DI,10

                MOV CX,20

LOOP_SORT_CHANGE:

                MOV AL,NAME_GRADE_SAVE[BX][SI]

                XCHG AL,NAME_GRADE_SAVE[BX][DI]

                XCHG AL,NAME_GRADE_SAVE[BX][SI]

                INC SI

                INC DI

                LOOP LOOP_SORT_CHANGE

 

 2、執行結果

圖1:(選單和輸入效果)

 

圖2:(直接輸出效果)

 

圖:3:(排序程式執行後結果)

 

圖4:(排序後輸出結果)

 

圖5:(求最大值輸出結果)

 

 

3、心得體會

通過本次綜合實驗,我對彙編程式的操作指令有了更加細緻的認識。由於本次實驗的實驗目的是完成一個學生成績管理系統,因此需要實現對學生成績的排序,這也是本次實驗的難點之一。在進行排序時,必須要實現名字與成績同時運動,雖然我們之前已經進行過對數字的氣泡排序,但那只是對數字進行交換,沒有考慮姓名的同步性問題。在解決這個問題時,我的方法是用20個位元組的儲存單元來儲存單個學生的個人資訊,而當判斷出成績大小需要交換時,我將指標移到單個學生和他下一個學生的第一個單元,然後迴圈20次,直接將一整塊資訊都進行交換。

另外一個難點是對學生成績輸入的處理,因為本次實驗的要求是不定位數成績輸入,我想到了兩種思路,一種是常規思路,每輸入一個數時,將臨時儲存單位temp(初值為0)中的數值乘10,再加上剛剛輸入的那個數,這樣的好處在於無論我輸入多少個數,最終的結果一定與我實際想要得到的數相同。另一種思路是不將它轉換成實際的數,而是將輸入的數當作字串處理,這樣使輸入輸出變得更加簡單了,但是當我在進行比大小的操作時就變得相對複雜了,因為我必須要首先比較兩個數的長短,如果相等的話再從高位向低位依次比較大小,比兩個數字直接比大小複雜了很多。

    最後,通過本次綜合實驗,我真的學習到了很多,而且說實話我找錯誤和發現記憶體異常的能力變得更強了,這都得益於這次綜合實驗中遇到的問題和bug。總之,本次綜合實驗讓我收穫頗豐。