;Antonín Neumann A11B0439P .h8300s .equ syscall,0x1FF00 ; simulated IO area .equ PUTS,0x0114 ; kod PUTS .equ GETS,0x0113 ; kod GETS ;*** PODPROGRAMY *** ; --- NASOBENI START nasobeni: ;E2 - 1. citatel ;R2 - 2. citatel ;ER3 - 1. citatel na 32 bitu ;ER2 - 2. citatel na 32 bitu ;E1 - ridici "promenna" cyklu ;ER0 - vysledek mov.l #1,ER1 ;zvednu hodnotu reg. E1 o 1 aby cyklus probehl spravne mov.w E2,R3 ;presunu 1. citatele aby byl na 32 bitu mov.w #0,E2 ;presunu 2. citatele aby byl na 32 bitu cyklus: add.l #1,ER1 ;inkrementace ridici "promenne" add.l ER3,ER0 ;pricte hodnotu 1. citatele k vysledku cmp.l ER2,ER1 ;test ukoncovaci podminky bls cyklus ;opakovani cyklu rts ;"return" ; --- NASOBENI KONEC ; --- NULOVANI REGISTRU START vynuluj: xor.l ER0,ER0 xor.l ER1,ER1 xor.l ER2,ER2 xor.l ER3,ER3 xor.l ER4,ER4 xor.l ER5,ER5 xor.l ER6,ER6 rts ;"return" ; --- NULOVANI REGISTRU START ; --- VSTUP Z ASCII DO HEXADECIMAL START (osetreni vstupu a prevod ASCII na HEX) input: mov.b @ER2+,R3L ;vezme prvni ASCII znak z bufferu a presune do R3L cmp.b #0x30,R3L ;porovnani s hodnotou 0x30 = 0 blt err ;pokud je mensi skoc na chybu => neni HEXA cislo cmp.b #0x46,R3L ;porovnani s hodnotou 0x46 = F bgt err ;pokud je vetsi skoc na chybu => neni HEXA cislo sub.w #0x30,R3 ;odecteni 0x30 = 0 cmp.b #0x9,R3L ;porovnani s hodnotou 0x9 = 9 bgt between ;pokud je vesti shift: ;prevod z ASCII na HEX or.b R3L,R4L ;"presun" poslednich 4 bitu z R3L do R4L mov.b @ER2,R3L ;presunu dalsi znak z pameti cmp.b #0x0A,R3L ;porovnam s 0x0A = LF = \n = konec radku ;pokud je to nulovy znak (LF), tak uz jsem vse zpracoval a ulozim to do pameti beq save_input cmp.b #0x3,R6L ;porovnavam pomocny regist pro pocet znaku beq err ;pokud je na vstupu vic jak 4 HEXA cisla skok na chybu shll.w #2, R4 ;provedu bitovy posun o 4 pozice doleva(v HEXa posunu shll.w #2, R4 ;cislo o 1 pozici) inc.b R6L ;inkrementace pomocneho registru pro pocet znaku bra input ;skok na zacatek cyklu between: ;zjisteni jestli vstup neni v rozmezi 0x3A - 0x40 v ASCII sub.w #0x7,R3 ;odectu 7 od registru aby se zjistilo rozmezi cmp.b #0xA,R3L ;porovnam s 0xA blt err ;pokud je mensi skoc na chybu => neni HEXA cislo cmp.b #0xF,R3L ;porovnam s 0xF bgt err ;pokud je vetsi skoc na chybu => neni HEXA cislo bra shift ;skacu na na provedeni bitoveho posunu save_input: ;zapis vysledneho 16b cisla do pameti mov.w R4,@ER5 ;presun cisla na adresu v pameti rts ;"return" err: ;vypis chybove hlasky pro spatny vstup mov.w #PUTS,R0 ;presun adresy konzole pro vypis do R0 mov.l #par4,ER1 ;presun adresy par4 do ER1 jsr @syscall ;volani podprogramu pro konzoli jmp _start ;skok na zacatek programu pro nove zadani vstupu ; --- VSTUP Z ASCII DO HEXADECIMAL KONEC ; --- VYSTUP DO ASCII START output: cmp.b #8, R4L ;porovnani poctu cifer(iteraci) beq konec ;pokud je to 8 iterace tak skoc na konec mov.l ER2,ER3 ;presun obsah registru ER2 do ER3 shlr.l #2,ER2 ;provedu bitovy posun o 4 pozice doprava (v HEXa posunu shlr.l #2,ER2 ;cislo o 1 pozici) inc.b R4L ;inkrementuji ridici "promenne" and.l #0xF, ER3 ;"vytazeni" poslednich 4 bitu cmp.l #0x9, ER3 ;porovnani hodnoty s 0x9 (9) bgt pricti ;pokud je vetsi nez 0x9 skoc na pricteni add.l #0x30,ER3 ;jinak pricti 0x30 (0) a pokracuj write: ;zapsani prevedene hodnoty do pameti mov.b R3L, @ER6 ;presunuti ASCII hodnoty z registru do pameti dec.l #1, ER6 ;snizeni adresy pameti o 1 bra output ;skok na zacatek cyklu pricti: add.w #0x37,R3 ;pricteni 0x37 pro prevedeni na A-F bra write ;skok na zapis do pameti konec: rts ;"return" ; --- VYSTUP DO ASCII KONEC ; --- ZAPIS KONCE RADKY 0x0A = LS = \n DO VYSTUPU START zapis_LF: add.l #8,ER6 mov.b #0x0A,R2L mov.b R2L,@ER6 dec.l #1,ER6 rts ;"return" ; --- ZAPIS KONCE RADKY 0x0A = LS = \n DO VYSTUPU KONEC ;*** DATOVA CAST *** .data citatel1_txt: .asciz "Citatel 1:\n" ;text pro zadani 1. citatele citatel2_txt: .asciz "Citatel 2:\n" ;text pro zadani 2. citatele soucin_txt: .asciz "Soucin:\n" ;text pro vypsani vysledku error: .asciz "NENI HEXA CISLO!\n" vystup_txt: .space 9 ;prostor pro vypsani hodnoty vysledku buffer: .space 10 ;vstupni buffer pro konzoli par1: .long citatel1_txt ;parametricky blok pro 1. citatele par2: .long buffer ;parametricky blok pro buffer par3: .long citatel2_txt ;parametricky blok pro 2. citatele par4: .long error ;parametricky blok pro chybu par5: .long soucin_txt ;parametricky blok pro vysledek par6: .long vystup_txt ;parametricky blok pro vystup .align 4 ;zarovnani adresy citatel1: .space 2 ;prostor pro ulozeni hodnoty 1. citatele citatel2: .space 2 ;prostor pro ulozeni hodnoty 2. citatele vysledek: .space 4 ;prostor pro ulozeni hodnoty vysledku .space 64 ;prostor pro zasobnik stack: ;delarace zasobniku ;*** KODOVA CAST *** .text .global _start _start: mov.l #stack, ER7 ;inicializace zasobniku jsr @vynuluj ;volani podprogramu pro nulovani registru mov.w #PUTS,R0 ;presun adresy konzole pro vypis do R0 mov.l #par1,ER1 ;presun adresy par1 do ER1 (1. citatel) jsr @syscall ;volani podprogramu pro konzoli mov.w #GETS,R0 ;presun adresy konzole pro nacteni do R0 mov.l #par2,ER1 ;presun adresy par2 do ER1 (buffer) jsr @syscall ;volani podprogramu pro konzoli mov.l #buffer, ER2 ;presun adresy bufferu do ER2 mov.l #citatel1, ER5 ;presun adresy 1. cinitele do ER5 jsr @input ;volani podprogramu pro overeni a prevod vstupu z ASCII jsr @vynuluj ;volani podprogramu pro nulovani registru mov.w #PUTS,R0 ;presun adresy konzole pro vypis do R0 mov.l #par3,ER1 ;presun adresy par1 do ER1 (2. citatel) jsr @syscall ;volani podprogramu pro konzoli mov.w #GETS,R0 ;presun adresy konzole pro nacteni do R0 mov.l #par2,ER1 ;presun adresy par2 do ER1 (buffer) jsr @syscall ;volani podprogramu pro konzoli mov.l #buffer, ER2 ;presun adresy bufferu do ER2 mov.l #citatel2, ER5 ;presun adresy 2. cinitele do ER5 jsr @input ;volani podprogramu pro overeni a prevod vstupu z ASCII jsr @vynuluj ;volani podprogramu pro nulovani registru mov.l #citatel1, ER4 ;presun adresy 1. citatel do ER4 mov.l #citatel2, ER5 ;presun adresy 2. citatel do ER5 mov.w @ER4, E2 ;presun 1. cinitele do E2 mov.w @ER5, R2 ;presun 2. cinitele do R2 jsr @nasobeni mov.l #vysledek, ER5 ;presun adresy vysledku do ER4 mov.l ER0, @ER5 ;presun vysledku do pameti jsr @vynuluj ;volani podprogramu pro nulovani mov.l #vysledek, ER5 ;presun adresy vysledku do ER5 mov.l #vystup_txt, ER6 ;presun adresy vystupu do ER6 jsr @zapis_LF ;volani podprogramu pro zapis 0x0A (\n) ;na posledni pozici | navratova adresa 0x054E | mov.l @ER5,ER2 ;presun vysledku z pameti do ER2 jsr @output ;volani podprogramu pro prevod vystupu na ASCII ;| navratova adresa 0x0554 | mov.w #PUTS,R0 ;presun adresy konzole pro vypis do R0 mov.l #par5,ER1 ;presun adresy par5 do ER1, vypise "Soucin:" jsr @syscall ;volani podprogramu pro konzoli mov.l #par6,ER1 ;presun adresy par6 do ER1 (vystupni text) jsr @syscall ;volani podprogramu pro konzoli end: ;bra end ;konec programu(zacykleni na miste) jmp _start ;zacykleni pro neustaly beh programu .end