@ Jan Potocki 2020 @ Definicje numerow funkcji systemowych i ich parametrow SYSEXIT = 1 SYSREAD = 3 SYSWRITE = 4 STDIN = 0 STDOUT = 1 @ Stale okreslajace rozmiar przetwarzanych danych num_length = 256 @ ...tego nie ruszac - inaczej stanie sie "cud nad klawiatura" :-D word_length = 4 buf_length = num_length * 2 num_words = num_length / word_length buf_words = buf_length / word_length .global main @ Segment niezainicjalizowanych danych .bss num1: .space num_length num2: .space num_length result: .space buf_length @ Segment kodu .text main: @ Glowna petla loop: mov r7, #SYSREAD @ Wczytanie danych ze standardowego wejscia mov r0, #STDIN @ ...funkcja systemowa read ldr r1, =num1 mov r2, #buf_length swi 0x0 @ UWAGA @ Tutaj wczytane zostana od razu obie liczby @ num1 i num2 sa w pamieci bezposrednio po sobie... @ ...i zostala przekazana do funkcji read dlugosc calego bloku cmp r0, #buf_length @ r0 - liczba wczytanych bajtow blt end @ Jezeli nie ma 512, to dane sie skonczyly ldr r8, =num1 @ r8 - adres pierwszej liczby ldr r9, =num2 @ r9 - adres drugiej liczby ldr r10, =result @ r10 - adres bufora na wynik eor r0, r0, r0 @ r0 - wartosc zero (do zapisu w pamieci) eor r4, r4, r4 @ r4 - indeks petli zerujacej @ Petla zerujaca bufor na wynik zero: str r0, [r10, r4, lsl#2] add r4, r4, #1 cmp r4, #buf_words blt zero eor r4, r4, r4 @ r0 - indeks pierwszej petli @ Mnozenie - petla zewnetrzna loop1: eor r2, r2, r2 @ r2 - miejsce na starsza czesc wyniku @ Flagi przeniesienia (potrzebne sa dwie i tego sie nie uprosci) eor r11, r11, r11 @ r11 - dla biezacego mnozenia (rejestry) eor r12, r12, r12 @ r12 - dla koncowego wyniku (w pamieci) eor r5, r5, r5 @ r5 - indeks drugiej petli @ Mnozenie - petla wewnetrzna loop2: ldr r0, [r8, r4, lsl#2] ldr r3, [r9, r5, lsl#2] umull r0, r1, r0, r3 @ Dodanie starszej czesci wyniku z poprzedniej iteracji msr apsr_nzcvq, r11 @ Ladowanie flag z r11 adcs r0, r0, r2 @ Dodawanie z przeniesieniem i ustawieniem flag mrs r11, apsr @ Zapis rejestru apsr (calego) w r11 mov r2, r1 @ Przechowanie starszej czesci wyniku w r2 add r6, r4, r5 @ r6 - indeks wyniku (suma indeksow obu petli) msr apsr_nzcvq, r12 @ Ladowanie flag z r12 ldr r1, [r10, r6, lsl#2] adcs r1, r0, r1 @ Dodawanie z przeniesieniem i ustawieniem flag str r1, [r10, r6, lsl#2] mrs r12, apsr @ Zapis rejestru apsr (calego) w r12 add r5, r5, #1 cmp r5, #num_words blt loop2 @ Koniec wewnetrznej petli @ Tutaj musimy sie jeszcze zajac najstarsza czescia wyniku @ (z ostatniej iteracji petli wewnetrznej) add r6, r6, #1 msr apsr_nzcvq, r11 @ Ladowanie flag z r11 adc r2, r2, #0 @ Dodawanie z przeniesieniem bez ustawiania flag msr apsr_nzcvq, r12 @ Ladowanie flag z r12 ldr r1, [r10, r6, lsl#2] adc r1, r1, r2 @ Dodawanie z przeniesieniem bez ustawiania flag str r1, [r10, r6, lsl#2] add r4, r4, #1 cmp r4, #num_words blt loop1 @ Koniec zewnetrznej petli mov r7, #SYSWRITE @ Wypisanie wyniku na standardowe wyjscie mov r0, #STDOUT @ ...funkcja systemowa write ldr r1, =result mov r2, #buf_length swi 0x0 b loop @ Koniec glownej petli end: mov r7, #SYSEXIT @ Funkcja systemowa exit... mov r0, #0 @ ...kod zakonczenia - 0 swi 0x0