20-bo‘lim
Amaliy loyiha - o'z protsessoringiz
13-bo'limdagi mashinaga ikki o'tishli assembler yozish, nishonlar, xato xabarlari va butun zanjirni yopish.
Ushbu bo‘lim mundarijasi
13-bo'limda virtual protsessor qurdik. Lekin dasturni unga qo'lda - har komandani alohida son qilib - yozdik.
19-bo'limda esa haqiqiy assemblerni ko'rdik. Endi o'zimiznikini yozamiz - va butun zanjir yopiladi:
assembler matni → assembler dasturi → mashina kodi → virtual protsessor → natija
Nima qo'limizda bor #
13-bo'limdan bizda ikki narsa bor: 32 bitli komanda formati va uni bajaradigan mashina.
| Qism | Qayerda qurilgan |
|---|---|
| Mantiqiy elementlar va sumator | 8-bo'lim |
| Registrlar, ALU, bayroqlar | 9-bo'lim |
| Komanda sikli | 10-bo'lim |
| Komanda formati va mashina | 13-bo'lim |
Yetishmayotgan yagona narsa - assembler. Uni shu bo'limda qo'shamiz.
Assembler #
Assembler ikki o'tishda ishlaydi - va buning aniq sababi bor.
Muammo: SAKRA halqa komandasi halqa nishoni qayerda
ekanini bilishi kerak. Lekin nishon kodda keyinroq
turishi mumkin.
Yechim: avval hamma nishonni topib chiqamiz, keyin komandalarni kodlaymiz.
Bu klassik muammo va uning nomi bor: oldinga havola (forward reference).
SAKRA tugadi ; tugadi qayerda? hali noma'lum
...
tugadi: ; mana shu yerda
Yechimlar:
| Usul | Izoh |
|---|---|
| Ikki o'tish | Avval nishonlar, keyin kod - eng sodda |
| Bir o'tish + tuzatish | Bo'sh qoldirib, oxirida to'ldirish |
Birinchisi ancha tushunarli, shuning uchun o'quv assemblerlarida odatda o'sha tanlanadi.
Xuddi shu muammo haqiqiy assemblerlarda ham, bog'lovchida ham (19-bo'lim), hatto C dagi funksiya prototiplarida ham uchraydi.
Butun zanjirni sinash #
Endi haqiqiy dastur - assembler matnida yozilgan Evklid algoritmi:
; Ikki sonning eng katta umumiy bo'luvchisi (Evklid algoritmi)
YUKLA r0, 48 ; birinchi son
YUKLA r1, 18 ; ikkinchi son
YUKLA r3, 0 ; taqqoslash uchun nol
halqa:
SOLISH r1, r3 ; r1 nolmi?
AGAR_NOL tugadi
KOCHIR r2, r0 ; r2 = r0
ayirish:
SOLISH r2, r1
AGAR_KICHIK qoldiq
AYIR r2, r1 ; r2 -= r1
SAKRA ayirish
qoldiq:
KOCHIR r0, r1 ; r0 = r1
KOCHIR r1, r2 ; r1 = qoldiq
SAKRA halqa
tugadi:
CHIQAR r0
TOXTA
Birinchi o'tish to'rtta nishonni topadi va ularning manzilini yozib oladi:
| Nishon | Manzil |
|---|---|
halqa | 3 |
ayirish | 6 |
qoldiq | 10 |
tugadi | 13 |
Ikkinchi o'tish har qatorni mashina kodiga aylantiradi. Birinchi to'rttasi:
| Manzil | Mashina kodi | Assembler |
|---|---|---|
| 0 | 0x01000030 | YUKLA r0, 48 |
| 1 | 0x01100012 | YUKLA r1, 18 |
| 2 | 0x01300000 | YUKLA r3, 0 |
| 3 | 0x0D130000 | SOLISH r1, r3 |
0x01000030 soniga diqqat bilan qarang:
| Bo'lak | Qiymat | Ma'nosi |
|---|---|---|
01 | 1 | YUKLA amali |
0 | 0 | maqsad: r0 |
0 | 0 | manba ishlatilmaydi |
0030 | 48 | yuklanadigan son |
13-bo'limdagi format aynan shunday ishlaydi.
Dasturni mashinada ishga tushirsak:
| Natija | |
|---|---|
| Komandalar soni | 15 |
| Bajarilgan qadamlar | 51 |
| Chiqish | 6 |
48 va 18 ning eng katta umumiy bo'luvchisi haqiqatan
6.
Zanjir yopildi. Evklid algoritmi assembler matnida yozildi, nishonlar manzilga aylandi, komandalar sonlarga kodlandi va bizning protsessorimizda bajarildi.
Xatolarni xabar qilish #
Yaxshi assembler faqat ishlashi kerak emas - xatoni tushunarli aytishi ham kerak. Bizniki shunday xabarlar beradi:
| Xato turi | Xabar |
|---|---|
| Noma'lum amal | 1-qator: noma'lum amal 'QOSHISH' |
| Noto'g'ri registr | 1-qator: 'r9' registr emas (r0-r3) |
| Topilmagan nishon | 1-qator: 'yoq_nishon' nishoni topilmadi |
| Takrorlangan nishon | 2-qator: 'boshi' takrorlandi |
Har xabarda qator raqami bor - bu eng muhim qism. Usiz katta dasturda xatoni topish juda qiyin bo'lardi.
Kompilyator yoki assembler yozayotgan bo'lsangiz, xato xabarlariga kod yozgancha vaqt sarflang.
Yaxshi xabarda uchta narsa bo'ladi:
| Element | Misol |
|---|---|
| Qayerda | 12-qator |
| Nima | 'r9' registr emas |
| To'g'risi qanday | (r0-r3) |
Uchinchisi ko'pincha unutiladi, lekin u eng foydali.
Rust kompilyatori aynan shu bilan mashhur bo'lgan: u nafaqat xatoni aytadi, balki tuzatishni ham taklif qiladi.
O'quv kodi sifatida u yetarli, lekin jiddiy ishlatish uchun emas:
| Muammo | Nima bo'ladi |
|---|---|
YUKLA r0 (argument yetishmaydi) | IndexError - tushunarsiz xato |
YUKLA r0, 99999 | Qiymat 16 bitga sig'maydi, jimgina kesiladi |
| Dastur xotiradan katta | Yuklashda IndexError |
| Nishon nomi amal bilan bir xil | Chalkashlik |
Har biri uchun aniq tekshiruv va tushunarli xabar kerak.
Bu 12-bo'limdagi xulosaning davomi: past darajadagi vositalar hech narsani kechirmaydi, shuning uchun tekshiruvlarni o'zingiz qo'yishingiz kerak.
Amaliy topshiriqlarda shu tekshiruvlarni qo'shishni taklif qilamiz.
- Evklid algoritmini qog'ozda 48 va 18 uchun qo'lda bajaring.
- 1071 va 462 uchun natijani hisoblang.
- Nishonlar jadvalini o'zingiz tuzib chiqing.
SAKRA halqakomandasi qanday manzilga aylanishini toping.0x01100012sonini maydonlarga ajrating.KOCHIR r2, r0komandasini qo'lda kodlang.- Nima uchun bir o'tish yetarli emasligini tushuntiring.
- Bir o'tishli yechim qanday ishlashini o'z so'zingiz bilan yozing.
- Xato xabarida qator raqami nima uchun muhimligini ayting.
- Fibonachchi dasturini (13-bo'lim) assembler matnida yozib ko'ring.
Xulosa #
- Assembler - matnni mashina kodiga aylantiradigan dastur.
- U ikki o'tishda ishlaydi: avval nishonlar, keyin komandalar.
- Sabab - oldinga havola: sakrash nishoni keyinroq turishi mumkin.
- Xuddi shu muammo bog'lovchida va funksiya prototiplarida ham uchraydi.
- Nishon - bu shunchaki manzilga berilgan nom.
- Izohlar va bo'sh qatorlar kodlashdan oldin olib tashlanadi.
- Xato xabarida qator raqami, sabab va to'g'ri shakl bo'lishi kerak.
- Butun zanjir yopildi: matn → assembler → mashina kodi → protsessor.
- Evklid algoritmi bizning mashinamizda 51 qadamda bajarildi.
- O'quv vositasida tekshiruvlar kam - jiddiy ishlatishdan oldin ularni qo'shish shart.
Darslik yakunida #
Yigirma bo'lim oldin 0.1 + 0.2 nima uchun 0.3 bermasligi
sir edi. Endi butun zanjirni ko'rasiz:
| Qadam | Bo'lim |
|---|---|
| Son bitlarga aylanadi | 2, 3, 5 |
| Bitlar ustida amal bajariladi | 4 |
| Amal mantiqiy elementlardan quriladi | 8 |
| Element ALU ga, ALU protsessorga yig'iladi | 9 |
| Komanda olinadi, dekodlanadi, bajariladi | 10 |
| Komandalar to'plami ISA ni tashkil qiladi | 11, 12 |
| Xotira ierarxiyasi tezlikni ta'minlaydi | 14, 15 |
| Konveyer va parallellik yana tezlashtiradi | 16, 17 |
| Tashqi dunyo uzilishlar orqali ulanadi | 18 |
| Kod kompilyatordan o'tib mashina kodiga aylanadi | 19 |
Va o'z protsessoringizni qurdingiz - NAND elementidan boshlab, assemblergacha.
Bundan keyin qayerga borish mumkin:
- "Operatsion tizimlar" - shu apparat ustida OT qanday ishlaydi;
- "Kompyuter tarmoqlari" - mashinalar qanday gaplashadi;
- "Algoritmlar va ma'lumotlar tuzilmasi" - endi Big-O ni kesh bilan birga o'qing;
- "Zamonaviy C++" yoki "Go" - past darajaga yaqin tillar.
Kompyuter sehrli quti emas. Bu - mantiqiy elementlar, registrlar va juda ko'p qatlam. Endi ularning hammasini bilasiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.