1. 実験の目的
- 解決すべき割り当てられた問題を分析して理解します。
- LC-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