Assembly ile ADuC841 – [2] İlk Adım İlk Örnek : Bellek, Register ve Makine Kodu
Bit Seviyesinde Kontrol ( Donanım Analiz)
Keil C51 programını indirerek ADuC841 ‘e kod yazmaya başlayacağız , lakin burda işin felsefesine odaklanarak bunu yapacağımız için donanım mimarisi üzerinden detaylıca işleyeceğiz.
İcona tıklayarak programın indereceğiniz anasayfaya gideceksiniz.

Programı kurun ve açın ardından aşağıdaki adımları takip ederek ilk örneğimiz için yapıyı hazır hale getirin.
-> Project
New uVision Project
->(Kendi Dosyanızın İçerisine) “projeAdı” ‘nı girin
-> Kaydet -> Search : “Aduc841” yazın
-> Hemen yandaki iki adet tiki işaretleyin “Use Extended Linker” ve “Use Extended Assembler”
-> Ok ‘ butonuna tıklayın
-> “Copy Start…” Hayır işaretleyin
-> Sol pencereden : Target : Source Group ‘a sol tık yaparak
-> Add New item Seçin
-> Asm File (s) ‘ yi seçin ve Name kısmına “altDosyaAdı” nı verin
-> Add ‘ butonuna tıklayınyeni proje metin dosyanız açıldı.
Başlıyoruz…
ilk kodumuzu yazalım ve donanım üzerinde analiz etmeye başlayalım.
|
1 2 3 |
#include "aduc841.h" mov 00h,#55h end |
#include "aduc841.h": aduc841 kütüphanesini ekledikend: programın sonumov: kopyalama fonksiyonu.
mov 00h, #55h : 00h adresindeki RAM hücresine 55h (decimal 85) değerini yazar.
Internal Data RAM
┌─────────────┐
│ 00h │ 55h │ ◄─── buraya yazıldı
│ 01h │ ?? │
│ 02h │ ?? │
│ … │
│ 1Fh │ ?? │ ◄─── Register Bank 0’ın sonu
│ … │
│ 7Fh │ ?? │
└─────────────┘
Kritik Detay — Register Bank Çakışması:
00hadresi aynı zamanda Register Bank 0’ın R0 register’ıdır. Yanimov 00h, #55hilemov R0, #55haynı fiziksel hücreye yazar! Bu çok önemli bir 8051 mimarisi detayıdır.
123456789 Register Bank 0 RAM AdresiR0 ────────────► 00hR1 ────────────► 01hR2 ────────────► 02hR3 ────────────► 03hR4 ────────────► 04hR5 ────────────► 05hR6 ────────────► 06hR7 ────────────► 07h
org 0000h :Origin” yani başlangıç adresi direktifi. Assembler’a “bundan sonra yazacağın makine kodunu 0000h adresinden itibaren yerleştir” der.
FLASH Bellek
┌─────────────┐
│ 0000h ◄─── CPU buradan başlar (Reset Vector)
│ 0001h
│ 0002h
│ …
└─────────────┘
Yukarıda verdiğimiz örneğin seviyesini biraz artıralım.
|
1 2 3 4 5 6 |
#include "aduc841.h" org 0000h mov 00h,#55h mov 01h,#66h mov r2,#77h end |
yenilik olarak ;
mov 01h, #66h : 01h adresine 66h (decimal 102) yazar.
Internal Data RAM
┌─────────────┐
│ 00h │ 55h │ ◄─── R0 = 55h
│ 01h │ 66h │ ◄─── R1 = 66h (buraya yazıldı)
│ 02h │ ?? │
└─────────────┘
mov r2, #77h : R2 register’ına 77h (decimal 119) değerini yazar.
Internal Data RAM
┌─────────────┐
│ 00h │ 55h │ ◄─── R0 = 55h
│ 01h │ 66h │ ◄─── R1 = 66h
│ 02h │ 77h │ ◄─── R2 = 77h (buraya yazıldı)
│ 03h │ ?? │
└─────────────┘
Bu sefer adres değil, register ismi kullanılmış. Assembler bunu otomatik olarak aktif register bank’ın R2 adresine çevirir. Varsayılan olarak Register Bank 0 aktiftir, yani bu
mov 02h, #77hile tamamen aynıdır.
mov 00hvemov r2arasındaki fark saf bir soyutlama katmanı farkıdır. İkisi de aynı donanım işlemini yapar. Amar2yazmak:
- Daha okunabilir
- Register bank değişikliklerine karşı daha güvenli
- Assembler’ın senin adına adres hesaplaması yapmasına izin verir
Genel Olarak Donanımda Yapılan İşlemler

Memory 1 — d:0 (Data RAM)
d: öneki = Internal Data RAM demek. Yani Keil bu pencerede CPU’nun içindeki RAM’i gösteriyor.
|
1 2 3 4 5 6 7 8 |
D:0x00: 55 ◄─── R0 = 55h (mov 00h, #55h) D:0x01: 66 ◄─── R1 = 66h (mov 01h, #66h) D:0x02: 77 ◄─── R2 = 77h (mov r2, #77h) D:0x03: 00 ◄─── R3 = 00h (dokunulmadı) D:0x04: 00 ◄─── R4 = 00h (dokunulmadı) D:0x05: 00 ◄─── R5 = 00h (dokunulmadı) D:0x06: 00 ◄─── R6 = 00h (dokunulmadı) D:0x07: 00 ◄─── R7 = 00h (dokunulmadı) |
Bu tam olarak beklediğimiz sonuç. Yazdığın 3 satır mov kodu, RAM’in ilk 3 hücresine değerlerini yerleştirdi. Geri kalanlar 00h çünkü onlara hiç dokunmadık.
Memory 2 — c:0 (Code / Flash Belleği)
c: öneki = Code Memory yani FLASH Program Belleği demek.
Şimdi burada çok ilginç bir şey var. Assembler senin yazdığın 3 satır kodu makine diline çevirdi ve FLASH’a yazdı. Satır satır decode edelim:
→ mov 00h, #55h = 3 byte yer kapladı
→ mov 01h, #66h = 3 byte yer kapladı
→ mov r2, #77h = 2 byte yer kapladı! ( daha kısa )
| Komut | Opcode | Boyut | Açıklama |
|---|---|---|---|
MOV direct,#data |
75h |
3 byte | Herhangi bir RAM adresine yaz |
MOV R0,#data |
78h |
2 byte | R0’a özel kısa komut |
MOV R1,#data |
79h |
2 byte | R1’e özel kısa komut |
MOV R2,#data |
7Ah |
2 byte | R2’ye özel kısa komut |
mov 00h, #55h → CPU şunu düşünür:
“Bana bir adres verdiler → önce adresi oku,
sonra o adrese git, sonra değeri yaz”
= 3 adım, 3 bytemov r2, #77h → CPU şunu düşünür:
“R2 zaten bende var, direk yazayım”
= 2 adım, 2 byte
—————————————————————————————————————————–
Şimdi göreceğimiz kod ise donanımda ciddi değişikler yapacak.
|
1 2 3 4 5 6 7 8 9 |
#include "aduc841.h" org 0000h mov 00h,#55h mov 01h,#66h mov r2,#77h setb psw.3 mov r0,#77h mov r2,#88h end |
setb psw.3 : PSW (Program Status Word) register’ının 3. bitini 1 yapar.
clr psw.3 : PSW (Program Status Word) register’ının 3. bitini 0 yapar.
Donanımsal: PSW, 8051’in en kritik SFR’larından biridir. Adresi D0h‘dır ve CPU’nun o anki durumunu tutar.
PSW Register (D0h)
┌────┬────┬────┬────┬────┬────┬────┬────┐
│ CY │ AC │ F0 │ RS1 │ RS0 │ OV │ F1 │ P │
│ D7 │ D6 │ D5 │ D4 │ D3 │ D2 │ D1 │ D0 │
└────┴────┴────┴────┴────┴────┴────┴────┘
▲
PSW.3 0= RS0
PSW.3 yani RS0 biti 1 yapıldı.
Aşağıdaki tablo çok önemli.
| RS1 | RS0 | Aktif Bank | RAM Adresleri |
|---|---|---|---|
| 0 | 0 | Bank 0 | 00h – 07h |
| 0 | 1 | Bank 1 | 08h – 0Fh |
| 1 | 0 | Bank 2 | 10h – 17h |
| 1 | 1 | Bank 3 | 18h – 1Fh |
setb psw.3 → RS0=1, RS1=0 → Register Bank 1 aktif oldu!
Internal Data RAM
┌─────────────────────────┐
│ 00h–07h │ Bank 0 (eski) │ ◄── artık aktif değil
│ 08h–0Fh │ Bank 1 (yeni) │ ◄── AKTİF BANK (RS0=1)
│ 10h–17h │ Bank 2 │
│ 18h–1Fh │ Bank 3 │
└─────────────────────────┘
mov r0, #77h : Ne yapar: Aktif bank’ın R0 register’ına 77h yazar.
Donanımsal: Bir önceki setb psw.3 ile Bank 1 aktif oldu. Dolayısıyla artık R0, 00h adresini değil 08h adresini işaret ediyor!
Internal Data RAM
┌──────────────────────────────┐
│ 00h: 55h ◄─ Bank0 R0 (eski)
│ 01h: 66h ◄─ Bank0 R1
│ 02h: 77h ◄─ Bank0 R2
│ …
│ 08h: 77h ◄─ Bank1 R0 (YENİ) ◄── buraya yazıldı
│ 09h: 00h ◄─ Bank1 R1
│ 0Ah: 00h ◄─ Bank1 R2
└──────────────────────────────┘
mov r2, #88h : Ne yapar: Aktif bank’ın (Bank 1) R2 register’ına 88h yazar.
Donanımsal: Bank 1’de R2, 0Ah adresine karşılık gelir.
Internal Data RAM
┌──────────────────────────────┐
│ 00h: 55h ◄─ Bank0 R0
│ 01h: 66h ◄─ Bank0 R1
│ 02h: 77h ◄─ Bank0 R2 (eski)
│ …
│ 08h: 77h ◄─ Bank1 R0
│ 09h: 00h ◄─ Bank1 R1
│ 0Ah: 88h ◄─ Bank1 R2 (YENİ) ◄── buraya yazıldı
└──────────────────────────────┘
Tüm RAM Durumu
|
1 2 3 4 5 6 7 8 9 10 11 |
Internal Data RAM (Program bittikten sonra) Bank 0 (artık pasif) Bank 1 (aktif) 00h: 55h ◄─ R0 08h: 77h ◄─ R0 01h: 66h ◄─ R1 09h: 00h ◄─ R1 02h: 77h ◄─ R2 0Ah: 88h ◄─ R2 03h: 00h ◄─ R3 0Bh: 00h ◄─ R3 04h: 00h ◄─ R4 0Ch: 00h ◄─ R4 05h: 00h ◄─ R5 0Dh: 00h ◄─ R5 06h: 00h ◄─ R6 0Eh: 00h ◄─ R6 07h: 00h ◄─ R7 0Fh: 00h ◄─ R7 |



