LC-3 kontrol komutları: BR, JMP, TRAP ve döngüler
Condition code'lara bakan BR komutu, offset hesabı, JMP/RET ve TRAP; sayaçlı ve sentinel döngüler, if/else kalıbı ve hex makine kodundan programı okuyup izlemek.
Geçen hafta komutlar hep sırayla çalışıyordu: her FETCH, PC’yi bir artırıyordu. Gerçek programlar ise karar verir (if) ve tekrar eder (döngü). Bunun için kontrol komutları (control instructions) var: PC’ye yeni bir değer yazarak sıradaki komutu değiştirirler. LC-3’te bunlar BR, JMP, JSR, TRAP ve RTI. Bu sayfada BR, JMP ve TRAP’i, sonra da onlarla kurulan döngü ve if kalıplarını görüyorsun.
Sınav soruları: BR’yi kodla ya da çöz (offset hesabı), hex olarak verilmiş bir programı çöz ve izle, bir döngünün kaç kez döndüğünü ve sonundaki register değerlerini bul.
BR: koşullu dallanma
0000 | n | z | p | PCoffset9
15-12 11 10 9 8-0
BR, condition code’lara bakar. Komutta 1 olan bitlerden biri o anki condition code ile eşleşirse dallanır: PC ← (artmış PC) + SEXT(PCoffset9). Eşleşmezse hiçbir şey yapmaz, program sıradaki komuta geçer.
| Assembly | n z p | Ne zaman dallanır? |
|---|---|---|
BRn | 1 0 0 | son değer negatif |
BRz | 0 1 0 | son değer sıfır |
BRp | 0 0 1 | son değer pozitif |
BRnz | 1 1 0 | ≤ 0 |
BRzp | 0 1 1 | ≥ 0 |
BRnp | 1 0 1 | ≠ 0 |
BR / BRnzp | 1 1 1 | her zaman |
| (000) | 0 0 0 | asla (NOP) |
İPUCU · BR neye bakıyor? BR, condition code’u en son register’a yazan komutun sonucuna bakar. Arada ST, STR, BR gibi CC’yi değiştirmeyen komutlar olabilir; onlar sayılmaz. Bir register’ı test etmek istiyorsan önce onu bir yere yaz:
ADD R1, R1, #0CC’yi R1’e göre ayarlar.
Offset hesabı
Aralık -256..+255. Geriye (döngünün başına) dallanırken offset negatiftir.
Kodlama örneği: BRn LOOP x3008’de, LOOP = x3002.
offset = x3002 - x3009 = -7
-7 (9 bit) = 1 1111 1001
0000 100 111111001 = x09F9
Çözme örneği: x0BFC, x3020’de.
0000 101 111111100
n=1 z=0 p=1 → BRnp
offset = 1 1111 1100 = -4
hedef = x3021 - 4 = x301D
JMP ve RET
1100 | 000 | BaseR | 000000
PC ← BaseR. Hedef bir register’da olduğu için belleğin her yerine atlayabilir (BR sadece ±256). JMP R2 = xC080. RET, JMP R7’nin takma adıdır (xC1C0); alt programdan ya da TRAP rutininden dönmek için kullanılır.
TRAP
1111 | 0000 | trapvect8
- R7 ← PC (artmış PC, dönüş adresi).
- PC ← M[ZEXT(trapvect8)]: x0000-x00FF arasındaki trap vector table’dan rutinin adresini al.
| Kod | Takma ad | İş |
|---|---|---|
| xF020 | GETC | karakter oku → R0 |
| xF021 | OUT | R0’ı yaz |
| xF022 | PUTS | R0’daki adresten string yaz |
| xF023 | IN | istem + karakter oku + yaz → R0 |
| xF025 | HALT | dur |
Döngü kalıpları
Sayaçlı döngü (counter-controlled)
Kaç kez döneceğin baştan belli. Sayaç bir register’da tutulur, her turda azaltılır, sıfır olunca çıkılır.
Çözümlü örnek: çarpma. LC-3’te MUL yok; 6 × 4 = 6 + 6 + 6 + 6.
.ORIG x3000
AND R3, R3, #0 ; R3 = 0 (sonuç)
LD R1, X ; R1 = 6
LD R2, Y ; R2 = 4 (sayaç)
LOOP ADD R3, R3, R1 ; R3 += 6
ADD R2, R2, #-1 ; sayaç--
BRp LOOP ; sayaç > 0 ise tekrar
HALT
X .FILL #6
Y .FILL #4
.END
tur R3 R2 CC BRp
1 6 3 P dön
2 12 2 P dön
3 18 1 P dön
4 24 0 Z düş
Sonuç R3 = 24. Makine kodu:
x3000 x56E0 AND R3, R3, #0
x3001 x2205 LD R1, X (x3002 + 5 = x3007)
x3002 x2405 LD R2, Y (x3003 + 5 = x3008)
x3003 x16C1 ADD R3, R3, R1
x3004 x14BF ADD R2, R2, #-1
x3005 x03FD BRp x3003 (x3006 - 3)
x3006 xF025 HALT
TUZAK · bir tur fazla. BRp yerine BRzp yazarsan R2 = 0 iken de döner, 5 tur çalışır, sonuç 30 olur. Sayacı 0’da bitirmek istiyorsan BRp kullan.
Sentinel döngü
Kaç eleman olduğu bilinmiyor; listenin sonunda özel bir değer (sentinel, genelde 0) var. Her eleman yüklenir, sentinel ise çıkılır.
Çözümlü örnek: negatifleri say.
AND R2, R2, #0 ; sayaç = 0
LEA R1, DATA ; R1 = dizinin adresi
LOOP LDR R3, R1, #0 ; R3 = *R1, CC ayarlanır
BRz DONE ; 0 → bitti
BRp NEXT ; pozitif → sayma
ADD R2, R2, #1 ; negatif → say
NEXT ADD R1, R1, #1 ; sonraki eleman
BRnzp LOOP
DONE ST R2, RESULT
HALT
RESULT .BLKW 1
DATA .FILL #5
.FILL #-3
.FILL #-8
.FILL #2
.FILL #-1
.FILL #0
Sonuç RESULT = 3. BRz ile BRp arka arkaya aynı CC’ye bakar, çünkü BR CC’yi değiştirmez.
if ve if/else
Kalıp: koşulun tersiyle atla. “x negatifse şunu yap” yazmak için “x negatif değilse (zp) atla” yazarsın.
Mutlak değer:
LD R1, V ; CC = V'nin işareti
BRzp DONE ; negatif değilse atla
NOT R1, R1 ; R1 = -R1
ADD R1, R1, #1
DONE ST R1, V
HALT
V .FILL #-25
Sonuç V = 25.
if/else: iki sayının büyüğü.
LD R1, A
LD R2, B
NOT R3, R2
ADD R3, R3, #1
ADD R3, R1, R3 ; R3 = A - B, CC ayarlandı
BRn BBIG ; A < B ise else kısmına
ADD R4, R1, #0 ; then: R4 = A
BRnzp END ; else'i atla
BBIG ADD R4, R2, #0 ; else: R4 = B
END HALT
A .FILL #-4
B .FILL #9
Sonuç R4 = 9. Then bloğunun sonundaki koşulsuz BRnzp END olmazsa program else bloğuna da düşer.
Hex’ten programı okumak
Sınavda bazen sadece makine kodu verilir. Tarif:
- Her kelimeyi 16 bite aç, opcode’a bak.
- Komutu assembly olarak yaz; BR hedeflerini adresle hesapla.
- Bir iz tablosu kur (register’lar, CC, dallanma).
x3000 x5020 AND R0, R0, #0
x3001 x1225 ADD R1, R0, #5
x3002 x1001 ADD R0, R0, R1
x3003 x127E ADD R1, R1, #-2
x3004 x03FD BRp x3002
x3005 xF025 HALT
R1: 5 → 3 → 1 → -1 R0: 5 → 8 → 9 sonuç R0 = 9
Sık yapılan hatalar
| Yanlış düşünce | Doğrusu |
|---|---|
| Offset = hedef - BR adresi | hedef - (BR adresi + 1) |
| BR kendi CC’sini üretir | BR son register yazımının CC’sine bakar |
| BRzp ile BRp aynı sayıda döner | BRzp bir tur fazla |
| x0000 geçersiz komut | nzp = 000 olan BR, NOP |
| JMP sadece ±256 uzağa | BaseR 16 bit, her yere |
| TRAP dönüş adresini PC’ye yazar | R7’ye yazar |
| if için koşulun kendisiyle dallan | Genelde koşulun tersiyle atla |
| then sonunda BRnzp gerekmez | Yoksa else de çalışır |
Kendini test et
Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.
Encode BRz with PCoffset9 = -6 in hex.
Cevabı göster
Format: 0000 | n z p | PCoffset9. BRz → n=0, z=1, p=0. -6 (9 bit) = 1 1111 1010.
0000 010 111111010 → 0000 0101 1111 1010 = x05FA.
Decode x0E05 located at address x3010. Where does it go, and when?
Cevabı göster
0000 111 000000101: n = z = p = 1, yani koşulsuz dallanma (BR ya da BRnzp). Hedef = x3011 + 5 = x3016.
A BRn LOOP instruction is at x3008 and LOOP is at x3002. What is the PCoffset9 and the machine code?
Cevabı göster
offset = hedef - (komut adresi + 1) = x3002 - x3009 = -7. -7 = 1 1111 1001.
0000 100 111111001 = 0000 1001 1111 1001 = x09F9.
What does an LC-3 BR instruction with n = z = p = 0 (for example x0000) do?
Cevabı göster
BR, test ettiği bitlerden biri condition code ile eşleşirse dallanır. Hiçbir bit seçilmemişse hiçbir zaman eşleşmez. PC sadece FETCH'teki +1 ile ilerler. x0000 bu yüzden NOP gibi davranır.
Encode JMP R2 and RET in hex.
Cevabı göster
Format: 1100 | 000 | BaseR | 000000. JMP R2: 1100 000 010 000000 = xC080. RET, JMP R7'nin takma adıdır: 1100 000 111 000000 = xC1C0. İkisi de PC ← BaseR yapar.
What are R3 and R2 when this program halts, and how many times is the instruction at LOOP executed?
AND R3, R3, #0
LD R1, X
LD R2, Y
LOOP ADD R3, R3, R1
ADD R2, R2, #-1
BRp LOOP
HALT
X .FILL #6
Y .FILL #4Cevabı göster
R2 sayaç (4). Her turda R3'e 6 eklenir, R2 bir azalır. R2: 3, 2, 1 (P → dön), 0 (Z → düş). Döngü 4 kez çalışır: R3 = 4 × 6 = 24. Bu, LC-3'te çarpmanın yoludur (MUL komutu yok).
In the previous program, BRp is replaced by BRzp. What is R3 now?
Cevabı göster
BRzp, R2 = 0 iken de döner. Döngü R2 = -1 olana kadar 5 kez çalışır: 5 × 6 = 30. Sayaçlı döngüde dallanma koşulu bir tur fazla ya da eksik çalıştırmanın en sık sebebidir.
The memory starting at x3000 contains x5020, x1225, x1001, x127E, x03FD, xF025. Decode the program and give R0 when it halts.
Cevabı göster
x5020 AND R0,R0,#0 · x1225 ADD R1,R0,#5 · x1001 ADD R0,R0,R1 · x127E ADD R1,R1,#-2 · x03FD BRp x3002 · xF025 HALT.
R1 = 5 → R0 = 5, R1 = 3 → R0 = 8, R1 = 1 → R0 = 9, R1 = -1 (N) → döngü biter. R0 = 5 + 3 + 1 = 9.
This program counts something in a list that ends with 0. What value is stored in RESULT?
AND R2, R2, #0
LEA R1, DATA
LOOP LDR R3, R1, #0
BRz DONE
BRp NEXT
ADD R2, R2, #1
NEXT ADD R1, R1, #1
BRnzp LOOP
DONE ST R2, RESULT
HALT
RESULT .BLKW 1
DATA .FILL #5
.FILL #-3
.FILL #-8
.FILL #2
.FILL #-1
.FILL #0Cevabı göster
LDR her elemanı yükler ve CC'yi ayarlar. 0 ise bitir (sentinel), pozitifse sayma, negatifse R2'yi artır. İki BR arka arkaya aynı CC'ye bakar, çünkü BR CC'yi değiştirmez. Negatifler: -3, -8, -1 → 3.
R1 = x8000. After ADD R2, R1, #0, is the following BRn taken? Why?
Cevabı göster
ADD R2, R1, #0, R1'i R2'ye kopyalar ve CC'yi ayarlar. x8000 = 1000 0000 0000 0000, bit 15 = 1 → -32768, N = 1. BRn dallanır. Bir register'ın işaretini test etmenin standart yolu, onu kendine ya da başka register'a #0 ekleyerek yazmaktır.
TRAP x25 is located at address x3001. What value is written to R7, and what is loaded into the PC?
Cevabı göster
TRAP, dönüş adresini R7'ye yazar: artmış PC = x3002. Sonra trapvect8 = x25 sıfırla genişletilir ve PC ← M[x0025] olur (servis rutininin başlangıcı). Rutin RET ile x3002'ye döner (HALT dönmez, makineyi durdurur).
A loop starts with R1 = 10. Each iteration adds 1 to R2 (initially 0), then executes ADD R1, R1, #-3 and BRzp back to the loop start. What are R2 and R1 at the end?
Cevabı göster
R1: 10 → 7 (P, dön) → 4 (dön) → 1 (dön) → -2 (N, düş). Gövde 4 kez çalıştı: R2 = 4, R1 = -2.
Doğrulama: Tüm BR/JMP/TRAP kodlamaları, offset'ler ve program izleri kendi LC-3 assembler + simülatörümüzde (verify/SEN2201/lc3.mjs) üretildi ve çalıştırıldı; döngü sayıları komut komut sayıldı (verify/SEN2201/08.mjs).