天天看點

【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會

目錄

目的與要求

内容與方法

步驟與過程

程式總體設計

核心資料結構——冒泡排序

調試過程

成績資料檔案data編寫和程式資料初始

成績複制

冒泡排序

A B計數儲存

核心代碼

結論或體會

目的與要求

分析和了解實驗指定的問題

利用LC-3的彙編代碼設計實作相關程式

熟練掌握循環、分支程式設計方法 

内容與方法

  • 背景
    • 16名學生成績排序,及統計分析
    • 成績分類規則
      • A:全班排名前25%,且成績在85分及以上
      • B:非A成績,全班排名前50%,且成績在75分及以上
      • C:非A、B成績
      • 要求
    • 使用LC-3彙編語言,編寫程式實作以上功能
  • 輸入
    • 16名學生成績,存儲于x3200至x320F
    • 每個成績為0至100之間,由16比特無符号整數表示
  • 輸出
    • 成績降序排序,并存儲于x4000至x400F記憶體位置,x4000位置成績為最高成績
    • 得A、B成績的學生總人數,分别存儲于x4100,及x4101位置

步驟與過程

程式總體設計

  • 根據題目,首先要實作的是成績的存儲。首先我用标号SCORE存儲成績首位址x3200,用data檔案記錄16個成績于起始位置:.ORIG x3200。
  • 其他重要位址和常量用标号表示如下:
SCORE	.FILL	x3200		;成績存放起始位址
RES		.FILL	x4000		;成績降序結果存放起始位址
Anum	.FILL	x4100		;存放A位址
Bnum	.FILL	x4101
nAscore	.FILL	-85			;A分數相反數
nBscore	.FILL	-75	
StuNUM	.FILL	16			;學生人數
ONE	    .FILL	1			;1
           
  • 算法流程——具體實作步驟如下:
    • 将成績複制到結果區:COPY循環
    • 冒泡排序:2層嵌套循環
    • 計算A B人數:各2個循環(CountA  CountB)
    • 結果儲存:STORE

核心資料結構——冒泡排序

C++代碼如下:

for(int i=1;i<n;i++){
	For(int j=0;j<n-I;j++){
		If(score[j]<score[j+1]){
			Swap(score[j],score[j+1])
		}
	}
}
           

調試過程

因為程式步驟較多,我進行分子產品編寫和調試,逐漸完成。

成績資料檔案data編寫和程式資料初始

  • 代碼編寫編譯(圖1)

R1存成績存放初始位址SCORE(x3200),R7存結果降序成績初始位址RES(x4000)。标号編寫。

【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會

Figure 1 data編寫和程式資料初始

  • 運作結果無誤(圖2)
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會

Figure 2 資料獲得和初始成功

成績複制

先将成績直接複制到結果區,在結果區排序。

  • 編寫編譯運作(圖3)
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會

Figure 3 成績複制代碼編譯運作

  • 結果正确,x3200和x4000存放的資料一樣(圖4)
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會

Figure 4 成績複制成功

冒泡排序

  • 編譯通過(圖5)
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會

Figure 5 冒泡成功編譯運作

  • 答案錯誤,代碼有誤,經過單步調試發現是每輪冒泡循環沒有把成績指針指向首位。(圖6)
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會

Figure 6 調試過程

  • 修改代碼(圖7)

每次循環都初始成績指針指向第一個成績。修改後答案正确

【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會

Figure 7 修改冒泡排序

A B計數儲存

         2個循環CountA和CountB周遊前4和前8個數,獲得A B人數,并儲存。(圖8)

【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會
【計算機系統1】3 LC-3彙編語言求成績等級目的與要求内容與方法步驟與過程結論或體會

Figure 8 程式結果正确

核心代碼

.ORIG	x3000 		;程式開始
	    LD	    R1,SCORE	;R1為存放成績初始位址
	    LD	    R7,RES		;R7存放成績降序結果位址
	    LD	    R2,StuNUM	;R2裝入學生人數
;
; 成績複制至結果區(loop)
;
COPY	LDR	R3,R1,0		;R3存成績
	    STR	R3,R7,0		;成績存結果
	    ADD	R1,R1,1		;下一個成績
	    ADD	R7,R7,1		;結果成績指針移向下一個
	    ADD	R2,R2,-1	;計數減1
	    BRp	COPY		;繼續循環直至全部複制

; 冒泡排序
;
	    LD	R2,ONE		;R2初始1,外層循環i,輪次
;
; 外層循環LOOP1(R2 0<i<n)
LOOP1	
	; 内層循環(R3 0<=j<n-i)
	;
		 LD      R7,RES		;R7存放成績降序結果首位址
		 AND     R3,R3,0		;R3清零, 裡層循環j,下标
		 ADD     R1,R2,-16	;R1=-(n-i)
	LOOP2	LDR	R4,R7,0		;R4存SCORE[j]
		    LDR	R5,R7,1		;R5存SCORE[j+1]
		    NOT	R6,R4	
		    ADD	R6,R6,1	
		    ADD	R6,R6,R5	;R6=SCORE[j+1]-SCORE[j]
		    BRnz	FLAG		;如果SCORE[j+1]<=SCORE[j],不用交換直接跳過
		;
		; 交換SCORE[j+1] SCORE[j]
		;
		STR	    R5,R7,0 
		STR	    R4,R7,1
		;
	FLAG
		ADD	R7,R7,1		;指向下一成績
		ADD	R3,R3,1		;j++
		ADD	R6,R3,R1	;R6=j-(n-i)
		BRn	LOOP2		;如果j<n-i,繼續内層循環
	;
	; 内層循環結束
	ADD	R2,R2,1	
	ADD	R6,R2,-16;R6=i-n
	BRn	LOOP1		;如果i<n,繼續外層循環
;
; 外層循環結束,冒泡排序完成

; 計數A B人數
;
	LD	R2,nAscore	;R2=-85
	LD	R3,nBscore
	AND	R1,R1,0		;R1清零,計數
	AND	R5,R5,0		;R5清零存A人數
	AND	R6,R6,0		;B人數
	LD	R7,RES		;R7存放成績降序結果首位址
;
; 獲得的A人數
;
CountA	LDR	R4,R7,0	
	ADD	R4,R4,R2	;R4=score-85
	BRn	CountB		;如果score<85,開始計數B
	ADD	R5,R5,1		;人數增加
	ADD	R7,R7,1		;移向下一分數
	ADD	R1,R1,1		;計數加1
	ADD	R0,R1,-4	;R0=計數-4
	BRn	CountA		;計數小于4,還在前25%繼續判斷A人數
;
; 獲得B的人數
;
CountB	LDR	R4,R7,0	
	ADD	R4,R4,R3	;R4=score-75
	BRn	STORE		;如果score<75,跳出B計數,進行儲存
	ADD	R6,R6,1		;人數增加
	ADD	R7,R7,1		;移向下一分數
	ADD	R1,R1,1		;計數加1
	ADD	R0,R1,-8	;R0=計數-8
	BRn	CountB		;計數小于8,還在前50%繼續判斷B人數
;
; 将A B人數儲存
;
STORE	STI	R5,Anum
	STI	R6,Bnum

	HALT			;程式運作結束
;
SCORE	.FILL	x3200		;成績存放起始位址
RES	.FILL	x4000		;成績降序結果存放起始位址
Anum	.FILL	x4100		;存放A位址
Bnum	.FILL	x4101
nAscore	.FILL	-85		;A分數相反數
nBscore	.FILL	-75	
StuNUM	.FILL	16		;學生人數
ONE	.FILL	1		;1
;		
	.END			;代碼結束
           

結論或體會

在本次實驗中,我首次嘗試了在LC3利用彙編代碼實作一個小程式,熟悉了了相關文法和良好的代碼分割。認識到了适用标号的諸多好處,如利用LD直接加載資料常量,将位址偏移的計算交給機器負責進而增加代碼的可讀性;同時也熟悉了關于标号的各種操作。通過規定檔案起始位置(.ORIG)實作多檔案連接配接的可能。

另外我熟悉了利用彙編代碼編寫循環和分支結構的過程,第一次嘗試用彙編代碼實作冒泡排序。嘗試了将一個實際問題通過問題分析,找到相應的算法實作流程及資料結構,進而通過逐漸編寫調試完成對問題的解決。

在本次實驗中我也糾正了一些自己的模糊認知。比如标号位址是一個常量,不能做指針移動。其他資料标号也同樣是常量,需要将其指派給寄存器才能進行變量操作。另外lc3僅有8個寄存器。需要合理循環利用寄存器。

繼續閱讀