/* vim: set ft=asm : */ .section .libinfo .ascii "KOSLIB 1.0.0 " .align 8 .quad KOSLIB .align 16 .ascii "LICENSE: C0" .align 8 .section .text // REM Standardne funkcie // DLzka TeXtu // Text je zakonceny byte-om (bajtom) 0x00 // Vstup 1 je na stacku KOSLIB: .asciz "-PUBLIC DOMAIN-" dltx: popq %rbp popq %rsi # vstup do funkcie xor %rcx, %rcx xor %rdx, %rdx pushq %rbp 1: movb (%rsi), %cl inc %rsi inc %rdx cmp $0, %cl jne 1b mov %rdx, %rax # vysledok do RAX (dlzka textu) ret .align 16 #otvori subor a nacita dany pocet bajtov (MAX 8) #Vystup v %rax = 1 az 8 bajtov so suboru danneho v %rdi otvorsuborbq: #(%rdi = subor, %rax = pocet bajtov) push %rbp mov %rsp, %rbp sub $16, %rsp movq %rax, -16(%rbp) mov $2, %rax #systemcall open = 2 mov $0, %rsi #RD_ONLY syscall #%rax = file-descriptor js 5f #nastala chyba, SIGN flag je nastaveny mov %rax, %rdi push %rax lea -8(%rbp), %rsi movq -16(%rbp), %rdx mov $2, %rax syscall pop %rdi mov $3, %rax syscall #nasledne zavrieme subor movq -8(%rbp), %rax # %rax = 1 az 8 bajtov so suboru 5: mov %rbp, %rsp pop %rbp ret dconout: mov %rdi, %rsi #vstup v %rdi push %rsi mov $1, %rax mov $1, %rdi xor %rdx, %rdx xor %rcx, %rcx 1: movb (%rsi), %cl inc %rsi inc %rdx cmp $0, %cl jne 1b pop %rsi syscall ret .align 16 .section .bss vstupy_rdi: .quad 0 vstupy_rcx: .quad 0 vstupy_rsp: .quad 0 zaciatok_tabulky: .quad 0 koniec_tabulky: .quad 0 adresa_pomocnej_spravy: .quad 0 .section .text #FIXME: musim zistit kedy prestat inkrementovat %rsp #lebo nam to segfaultne vstpy:#(%rdi, %rsi, %rdx, %rcx, %r8) #%rdi = adresa tabulky #%rsi = pocet elemtov v tabulke #%rdx = velkost jedneho elemetu v tabulke #%rcx = adresa pomocnej spravy #%r8 = adresa funkcie pre vychodzie nastavenia pop %rbp movq %rcx, %mm7 #adresa pomocnej spravy movq (%rsp), %rcx # pocet vstupov cmp $1, %rcx jg 1f push %rbp jmp *%r8 1: movq %rcx, %mm0 #%rcx zaloha movq %rdi, %mm1 #zaloha orig. %rdi movq %rdi, %mm2 #pomocny register %mm2 movq %rsp, %mm3 #orig %rsp add $8, %rsp #vypocitame koniec tabulky v %rdi mov %rdx, %rax mul %rsi mov %rdi, %rbx add %rax, %rbx movq %rbx, %mm5 #%mm5 = koniec tabulky #iterjueme cez tabulku v %rdi 10: movw (%rdi), %dx #%dx = 2 bajty pre switch movq (%rsp), %rbx # %rsp = adresa na adresu movzxw (%rbx), %rbx # %rbx = adresa => %rbx = 2 bajty cmp %bx, %dx #porovname 2 bajty switchov je 20f #---ak sa bajty rovnaju, mame switch #---ak sa switch nerovna prednastavenym switchom #v tabulke movq %mm5, %rbx add $10, %rdi cmp %rbx, %rdi je 9f #---koniec iteracie tabulky jmp 10b 20: add $2, %rdi movq (%rdi), %rbx # %rbx = adresa funkcie v tabulke add $8, %rdi # posunieme %rdi na dalsi slot v tabulke movq %rdi, %mm1 # ulozime si %rdi dec %rcx # aj parameter pre switch je vstup movq %rcx, %mm0 add $8, %rsp #posunieme %rsp na vstup pre switch movq (%rsp), %rdi #podla konvencie, %rdi ma prvy vstup call *%rbx #fall-through 9: movq %mm1, %rdi movq %mm0, %rcx add $8, %rsp dec %rcx jnz 10b #fall-through movq %mm3, %rsp mov (%rsp), %rcx cmp $1, %rcx jg 5f #nespravne volanie programu #ak je %rcx po vsetkych iteraciach 0 #a originalne %rcx nieje 1, tak #nebol spravne spusteny program #takze zobrazime pomocnu spravu a #program ukoncime. #subroutina sa spusit aj ked #je pocet vstupov 1 (nazov programu) pushq adresa_pomocnej_spravy call dconout progend $0 5: push %rbp ret ramnajdib: # %rdi = cielova adresa # %al = hladany byte # %rcx = max iteracii xor %rbx,%rbx 8: movb (%rdi), %bl cmp %al, %bl je 11f inc %rdi inc %rbx test %rcx, %rcx loopne 8b 1: test %rcx, %rcx jnz 11f mov $-1, %rax ret 11: mov %rbx, %rax # %rax = index kde sa nasiel byte ret ramporovb: # %rsi = zdroj (nemenny pointer) # %rdi = ciel (premenny pointer) xor %rcx, %rcx dec %rcx 8: inc %rcx movb (%rsi), %al movb (%rdi), %ah inc %rdi cmp %al,%ah jne 8b dec %rdi mov %rcx, %rax # %rax = index posledneho byte-u ktory sa nerovna # %rdi = pointer na zaciatok rozdielu ret .