LC-3 機械語プログラミング実験 成績募集中

1. 実験の目的

  1. 解決すべき割り当てられた問題を分析して理解します。
  2. LC-3 のアセンブリ コードを使用して、関連プログラムを設計および実現します。
  3. LC-3 エミュレータを通じて関連プログラムをデバッグおよび実行し、正しい結果を取得します。

2. 実験内容

配列を使用して学生の成績を並べ替えます。

背景: 教師は生徒の成績を決定するためにあなたの助けを必要としています。彼女は、クラス内での生徒のランクとテストの得点に基づいて生徒の最終成績を決定したいと考えています。

具体的なグレード要件は次のとおりです。

  • 生徒の得点がクラスの上位 25% にランクされ、テストの得点が 85 点以上の場合、生徒は A を取得できます。
  • A を獲得できないが、テストのスコアが 75 以上でクラスの上位 50% にランクされている場合、その生徒は B を獲得できます。
  • 残りの生徒は全員Cです

特定の状況:

  • 生徒は全部で 16 人で、各生徒には 1 つの学年しかありません
  • このクラスの成績を並べ替えるプログラムをアセンブリ言語で作成します。
  • プログラムでは、生徒の成績を並べ替えてから、A と B を獲得した生徒の数をカウントする必要があります。プログラムはx3000から始まります

プログラムへの入力:

  • クラス内の 16 人の生徒の順位付けされていない成績。
  • 各分数は、16 ビットの符号なし数値で表される 0 ~ 100 の整数です。
  • スコアは 16 の連続したメモリ位置に保存されます (x3200 から始まり、各位置に 1 つのスコア)。
  • 最後の部分は x320F に格納されます
  • すべてのスコアは互いに異なると想定できます (各スコアは一意です)。

プログラムの出力 (プログラムには 2 つの出力が必要です):

  • 16 人の生徒の得点が並べ替えられます。スコアは連続したメモリ位置で降順に並べ替える必要があります。メモリ アドレスごとに 1 つのスコアが x4000 から保存されます。つまり、x4000 には最高のスコアが保存されます。
  • A と B を受け取った生徒の数。A を獲得した生徒の数は x4100 に保存され、B を獲得した生徒の数は x4101 に保存される必要があります。

3. 実験手順と結果

1. 実験の概要と実施方法

まず、16 スコアの元のデータをメモリ x3200 に入力し、一周ループして x4000 にコピーします。

バブル ソートを使用して新しいアドレスの降順に並べ替え、ランキングを取得します。最後に、配列を x4000 でフィルターして、成績 A と成績 B を取得した生徒の数を数えます。全体のフローチャートは次のとおりです。
ここに画像の説明を挿入
上記は抽象的かつ一般的なプロセスであり、具体的な実装方法は以下に展開されます。各ステップの具体的なフローチャートを以下に示します。

a) 16 個のデータのコピーを完了します

アルゴリズムのフローチャートは次のとおりです。
ここに画像の説明を挿入
サイクルが do ループ構造を採用していることが簡単にわかります。

注目すべきところはたくさんあります。たとえば、R3 に値を割り当てるには、[-16, 15] の即値の制限により、完了までに 2 回かかります。*R2 <- *R1 を実現したい場合は、LDR と STR の 2 つの命令を使用して完了できます。それに加えて、レジスタ R0 を使用して新しいアドレス x4000 を長期保持します。アセンブリ コードを図に示します。

ここに画像の説明を挿入

b) バブルソート 16 データ

プロセスを理解しやすくするために、次の図に示すように、まず C++ 言語を使用してアルゴリズムを実装しました。 対応
ここに画像の説明を挿入
するアルゴリズムのフローチャートは次のとおりです。
ここに画像の説明を挿入
C++ 言語では for ループを使用したためです。それをアセンブリ言語に変換する過程で、Jump-to-middle 構造を採用しました。アセンブリコードは次のとおりです。
ここに画像の説明を挿入

c) 16 データのスクリーニングと評価

また、理解を容易にするために、最初に C++ プログラミングを使用します。C を取得した生徒の数を数える必要がないため、サイクルは 8 ラウンド後に終了できます。コードは次のとおりです。
ここに画像の説明を挿入
その後にフローチャートが続きます。
ここに画像の説明を挿入
アセンブリのプロセスでは、if ステートメントに複雑な式を使用できないため、C++ の goto ステートメントと同様に、より多くの条件付きジャンプが使用されます。ループの実装では、依然として中間へのジャンプ構造が採用されています。

ここに画像の説明を挿入
85 と 75 などのデータとの比較が複数あるため、減算を使用すると、レジスタに 1 を加算して反転するという操作が頻繁に実行され、時空間リソースの無駄であることは間違いありません。この問題を解決するために、レジスタには -85 と -75 のみを格納し、比較するときにそれらを直接加算 (減算に相当) できるようにすることで、より優れています。

2. アセンブリコードの読み込み

さらに LC3Edit で編集を完了し、obj ファイルを生成し、図に示すようにそれを LC3 シミュレーターにロードし、生徒の成績の元のデータを x3200 の場所に保存すると、実験を実行できます。
ここに画像の説明を挿入

3. コードの機能テストと正当性検査。

以下では主に 2 つの代表的な例を使用します。これら 2 つのサンプル グループには、繰り返し値や境界値はありません

例 1: 75 85 90 60 73 87 100 38 66 80 76 82 93 95 74 86

ここに画像の説明を挿入
実行結果は下図の通りです。
ここに画像の説明を挿入
x4000にデータがコピーされていることがわかります。ソート機能は正常に動作します。
ここに画像の説明を挿入
4100 の値は 4、x4101 の値は 4 です。4 人の生徒が A を獲得し、4 人が B を獲得したと説明します。これは計算結果と一致しています。

例 2: 75 85 60 61 73 84 100 38 66 53 76 82 72 95 74 80

ここに画像の説明を挿入
実行結果は下図の通りです。
ここに画像の説明を挿入
x4000でソートされたデータが見られることが分かります。
ここに画像の説明を挿入
同時に、x4100 と x4101 では 3 人が A 評価、5 人が B 評価を得ていることがわかります。この結果は客観的な現実と一致しています。

完全なコード

;author: CAO-Wuhui
;date: 2021.5.17
;function: Sort students' grades
;
;
;
		.ORIG	x3000	;起始地址
;
;完成对原始数据的拷贝
;
		LD	R1	DATA	;R1指向源地址
		LD	R2	RESULT	;R2指向目的地址
		AND	R0	R0	#0	;R0长期指向目的地址
		ADD	R0	R0	R2		
		AND R3 R3 #0	
		ADD R3 R3 #1
		ADD R3 R3 #15	;R3 = 16,循环次数
;
;循环,do-loop结构,将输入数据拷贝到目的地址
;

INIT_LOOP	LDR	R4	R1	#0	;R4 = *R1
			STR R4	R2	#0	;*R2 = R4
;
			ADD	R1	R1	#1
			ADD R2	R2	#1
			ADD	R3	R3	#-1
			BRp	INIT_LOOP

;
;冒泡排序,双重循环均采用 jump-to-middle 结构
;

		AND	R1	R1	#0

		ADD	R1	R1	#1	;i = 1
		BRnzp MIDDLE1
LOOP1	AND	R2	R2	#0	;j = 0
		BRnzp	MIDDLE2	;

LOOP2	ADD	R3	R0	R2
		ADD	R4	R3	#1
		LDR	R5	R3	#0	;R5 <- *R3
		LDR	R6	R4	#0	;R6	<- *R4
		
		NOT	R7	R6
		ADD	R7	R7	#1
		ADD	R7	R7	R5
		BRzp	END2
;
;exchange arr[j] and arr[j + 1]
;
		STR	R5	R4	#0
		STR	R6	R3	#0

END2	ADD	R2	R2	#1
MIDDLE2	ADD	R3	R1	R2
		ADD	R3	R3	#-16
		BRn	LOOP2

		ADD	R1	R1	#1
MIDDLE1	ADD	R3	R1	#-16
		BRn	LOOP1

;
;排序结束
;以下开始筛选等级
;循环依旧采用 jump-to-middle 结构
;

		AND	R1	R1	#0	;i = 0
;
;初始化R6 = -85,R7 = -75
;
		LD	R6	A_GRADE	;
		LD	R7	B_GRADE	;
		NOT	R6	R6
		ADD	R6	R6	#1
		NOT	R7	R7
		ADD	R7	R7	#1
;
		AND	R2	R2	#0	;cntA = 0,A的人数
		AND	R3	R3	#0	;cntB = 0,B的人数
;
		BRnzp	MIDDLE3
LOOP3	ADD	R4	R1	#-4
		BRzp	IS_B
;
		ADD	R4	R0	R1	;R4 = arr[i]
		LDR	R4	R4	#0	;
		ADD	R5	R4	R6	;if
		BRn	IS_B
		ADD	R2	R2	#1	;cntA++
		BRnzp	NEXT
;
IS_B	ADD	R4	R0	R1	;R4 = arr[i]
		LDR	R4	R4	#0	;
		ADD	R5	R4	R7	;if
		BRn	NEXT
		ADD	R3	R3	#1	;cntB++
;		
NEXT	ADD	R1	R1	#1
MIDDLE3	ADD	R4	R1	#-8
		BRn	LOOP3
;
;最后将结果保存到指定位置
;
		LD	R1	A_CNT
		STR	R2	R1	#0
		LD	R1	B_CNT
		STR	R3	R1	#0
;
		HALT
;
DATA	.FILL	x3200
RESULT	.FILL	x4000
A_CNT	.FILL	x4100
B_CNT	.FILL	x4101
A_GRADE	.FILL	x0055		
B_GRADE	.FILL	x004B

.END 

おすすめ

転載: blog.csdn.net/weixin_46655675/article/details/130858363