LC-3-Maschinencode-Programmierexperiment auf der Suche nach Noten

1. Zweck des Experiments

  1. Analysieren und verstehen Sie die zugewiesenen zu lösenden Probleme.
  2. Verwenden Sie den Assembler-Code von LC-3, um zugehörige Programme zu entwerfen und zu realisieren.
  3. Debuggen Sie verwandte Programme und führen Sie sie über den LC-3-Emulator aus, um korrekte Ergebnisse zu erhalten.

2. Experimenteller Inhalt

Sortieren Sie die Noten der Schüler mithilfe eines Arrays.

Hintergrund: Eine Lehrerin benötigt Ihre Hilfe, um die Note des Schülers zu ermitteln. Sie möchte die Abschlussnote des Schülers anhand der Rangfolge der Schülernote in der Klasse und des Testergebnisses ermitteln.

Die spezifischen Notenanforderungen lauten wie folgt:

  • Wenn die Punktzahl des Schülers zu den besten 25 % der Klasse gehört und das Testergebnis 85 Punkte oder mehr beträgt, kann der Schüler eine Eins erhalten
  • Wenn ein Schüler keine Eins erreichen kann, aber mit einem Testergebnis von 75 oder mehr zu den besten 50 % der Klasse gehört, kann er eine Zwei erhalten
  • Der Rest der Schüler ist allesamt C

Spezifische Situation:

  • Insgesamt gibt es 16 Schüler und jeder Schüler hat nur eine Note
  • Schreiben Sie ein Programm zum Sortieren der Noten für diese Klasse in Assembler.
  • Ihr Programm muss die Noten der Schüler sortieren und dann die Anzahl der Schüler zählen, die die Noten „Eins“ und „Zwei“ erhalten haben. Programm beginnt mit x3000

Eingabe in das Programm:

  • Unbewertete Noten der 16 Schüler der Klasse;
  • Jeder Bruch ist eine Ganzzahl von 0 bis 100, dargestellt durch eine 16-Bit-Zahl ohne Vorzeichen
  • Punkte werden an 16 aufeinanderfolgenden Speicherorten gespeichert – ein Punkt pro Ort; beginnend mit x3200;
  • Der letzte Bruch wird in x320F gespeichert
  • Sie können davon ausgehen, dass sich alle Bewertungen voneinander unterscheiden (jede Bewertung ist einzigartig).

Die Ausgabe des Programms (Ihr Programm muss zwei Ausgaben haben):

  • Die Noten von 16 Schülern werden sortiert. Die Punkte müssen in absteigender Reihenfolge in aufeinanderfolgenden Speicherorten sortiert werden – ein Punktestand pro Speicheradresse, gespeichert ab x4000; d. h. x4000 speichert den höchsten Punktestand
  • Die Anzahl der Schüler, die die Noten „A“ und „B“ erhalten haben. Die Anzahl der Schüler mit der Note „A“ muss in x4100 gespeichert werden und die Anzahl der Schüler mit der Note „B“ muss in x4101 gespeichert werden

3. Experimentelle Verfahren und Ergebnisse

1. Die allgemeine Idee und Durchführung des Experiments

Zunächst sollten die Originaldaten von 16 Scores in den Speicher x3200 eingegeben und durch eine Schleife auf x4000 kopiert werden.

Verwenden Sie die Blasensortierung, um die neue Adresse in absteigender Reihenfolge zu sortieren und so die Rangfolge zu ermitteln. Filtern Sie abschließend das Array bei x4000, um die Anzahl der Schüler zu zählen, die die Noten A und B erhalten haben. Das Gesamtflussdiagramm sieht wie folgt aus:
Fügen Sie hier eine Bildbeschreibung ein
Das Obige ist ein abstrakter und allgemeiner Prozess, und die spezifische Implementierungsmethode wird im Folgenden erweitert. Das spezifische Flussdiagramm jedes Schritts wird unten bereitgestellt.

a) Vervollständigen Sie die Kopie von 16 Daten

Das Flussdiagramm des Algorithmus sieht wie folgt aus:
Fügen Sie hier eine Bildbeschreibung ein
Es ist leicht zu erkennen, dass die Schleife die Do-Loop-Struktur annimmt.

Es gibt viele Orte, auf die man achten sollte. Um beispielsweise R3 einen Wert zuzuweisen, muss dieser aufgrund der Beschränkung des unmittelbaren Werts in [-16, 15] zweimal abgeschlossen werden. Und wenn Sie *R2 <- *R1 realisieren möchten, können Sie zur Vervollständigung zwei Anweisungen LDR und STR verwenden. Außerdem verwende ich Register R0, um die neue Adresse x4000 langfristig zu halten. Der Assembler-Code ist in der Abbildung dargestellt:

Fügen Sie hier eine Bildbeschreibung ein

b) Blasensortierung von 16 Daten

Um den Prozess verständlicher zu machen, habe ich den Algorithmus zunächst in der Sprache C++ implementiert, wie in der folgenden Abbildung dargestellt: Das
Fügen Sie hier eine Bildbeschreibung ein
entsprechende Flussdiagramm des Algorithmus sieht wie folgt aus:
Fügen Sie hier eine Bildbeschreibung ein
Denn in der Sprache C++ habe ich eine for-Schleife verwendet. Bei der Übertragung in die Assemblersprache habe ich dann die Jump-to-middle-Struktur übernommen. Der Assembler-Code lautet wie folgt:
Fügen Sie hier eine Bildbeschreibung ein

c) Screening und Bewertung von 16 Daten

Um das Verständnis zu erleichtern, verwenden Sie zunächst die C++-Programmierung. Da die Anzahl der Schüler, die C erreichen, nicht gezählt werden muss, kann der Zyklus nach 8 Runden beendet werden. Der Code lautet wie folgt:
Fügen Sie hier eine Bildbeschreibung ein
gefolgt vom Flussdiagramm.
Fügen Sie hier eine Bildbeschreibung ein
Im Assemblierungsprozess können keine komplexen Ausdrücke für die if-Anweisung verwendet werden, daher werden mehr bedingte Sprünge verwendet, ähnlich der goto-Anweisung von C++. Die Implementierung der Schleife übernimmt weiterhin die Jump-to-Middle-Struktur.

Fügen Sie hier eine Bildbeschreibung ein
Da mehrere Vergleiche mit Daten wie 85 und 75 erforderlich sind, wird bei Verwendung der Subtraktion häufig die Operation des Invertierens und Addierens von eins zum Register durchgeführt, was zweifellos eine Verschwendung von Raum-Zeit-Ressourcen darstellt. Um dieses Problem zu lösen, werden nur -85 und -75 im Register gespeichert, sodass sie beim Vergleich direkt addiert werden können (entspricht einer Subtraktion), was besser ist.

2. Laden des Assembler-Codes

Schließen Sie die Bearbeitung weiterhin in LC3Edit ab, generieren Sie die OBJ-Datei und laden Sie sie wie in der Abbildung gezeigt in den LC3-Simulator. Speichern Sie die Originaldaten der Schülernoten am Speicherort x3200. Anschließend kann das Experiment durchgeführt werden.
Fügen Sie hier eine Bildbeschreibung ein

3. Code-Funktionstest und Korrektheitsprüfung.

Im Folgenden werden hauptsächlich zwei repräsentative Beispiele verwendet. In diesen beiden Probengruppen gibt es keine wiederholten Werte und Grenzwerte .

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

Fügen Sie hier eine Bildbeschreibung ein
Das laufende Ergebnis ist in der folgenden Abbildung dargestellt:
Fügen Sie hier eine Bildbeschreibung ein
Es ist ersichtlich, dass die Daten auf x4000 kopiert wurden. Die Sortierfunktion funktioniert einwandfrei.
Fügen Sie hier eine Bildbeschreibung ein
Der Wert bei 4100 ist 4 und der Wert bei x4101 ist 4. Erklären Sie, dass 4 Schüler die Note A und 4 die Note B erhalten haben. Dies steht im Einklang mit den Berechnungsergebnissen.

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

Fügen Sie hier eine Bildbeschreibung ein
Das laufende Ergebnis ist in der folgenden Abbildung dargestellt:
Fügen Sie hier eine Bildbeschreibung ein
Es ist ersichtlich, dass die sortierten Daten bei x4000 angezeigt werden.
Fügen Sie hier eine Bildbeschreibung ein
Gleichzeitig ist bei x4100 und x4101 zu erkennen, dass 3 Personen die Note A und 5 Personen die Note B erhielten. Dieses Ergebnis entspricht der objektiven Realität.

Vollständiger Code

;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 

Supongo que te gusta

Origin blog.csdn.net/weixin_46655675/article/details/130858363
Recomendado
Clasificación