
#1 Kontrolinio darbo užduočių šaltinis:
VU MIF // Vilniaus Universitetas, Matematikos ir informatikos fakultetas
Kompiuterių architektūra 1 kursas
http://uosis.mif.vu.lt/~julius/2008Rud/Uzd1.html
Priemonės: GNU Assembler, XCode 4, Mac OS X
XCode 4 Asemblerio Projekto šablonas: XCode 4 Assembler Project Template
Užduotis: Parašykite programą, kuri įvestoje simbolių eilutėje mažąsias raides pakeičia didžiosiomis ir atspausdina eilutės ilgį; Pvz.: įvedus “abSDGasR” turi atspausdinti “ABSDGASR (ilgis 8)”.
# Parašykite programą, kuri įvestoje simbolių eilutėje mažąsias raides # pakeičia didžiosiomis ir atspausdina eilutės ilgį; # Pvz.: įvedus "abSDGasR" turi atspausdinti "ABSDGASR (ilgis 8)" # 32-bit .intel_syntax .data infomsg: .ascii "Įveskite eilutę [ilgis 0-1024]\n" infomsglen: .long . - infomsg inputmsg: .space 1024, 0 inputmsglen: .long . - inputmsg outmsg: .space 1024, 0 outmsglen: .long . - outmsg buffer2: .space 1024, 0 outpliusmsg: .ascii " (Ilgis " outpliusmsglen: .long . - outpliusmsg .text _syscall: int 0x80 ret .globl start start: push [infomsglen] push infomsg push 1 mov eax, 4 call cs:_syscall add esp, 12 push [inputmsglen] push inputmsg push 0 mov eax, 3 call cs:_syscall add esp, 12 mov [inputmsglen], eax mov ecx, 0 mov esi, inputmsg L_back: cmp ecx, [inputmsglen] je cs:L_end lodsb al, [esi] cmp al, 0x61 # 0x61 - a, 0x7a jge cs:L_upChar jmp cs:L_gotoNext L_upChar: cmp al, 0x7a # 0x7a - z jg cs:L_gotoNext sub al, 0x20 # skirtumas tarp a ir A mov [outmsg+ecx], al inc ecx jmp cs:L_back L_gotoNext: mov [outmsg+ecx], al inc ecx jmp cs:L_back L_end: mov ebx, 0 # grįžus iš L_space nustatome naujas reikšmes tolesniam skaičiavimui mov eax, [inputmsglen] dec eax mov [inputmsglen], eax mov ecx, 10 L_next: mov edx, 0 # edx = 0; tam, kad dalyba būtų teisinga div ecx # daliname eax (žodžio ilgis) iš ecx (10) reikia kai žodis ilgesnis už 9, tinkamai atspausdinti simbolį add edx, 0x30 # po dalybos edx lieka dalybos liekana prie jos pridėsime 0x30, gauname korektiška ascii simbolio skaičių atsakymo spausdinimui push edx # gautą atsakymą išsaugome dėkle (stack) inc ebx # ebx kaip skaitliukas kiek išsaugota dėkle (stack) simbolių cmp eax, 0 # tikriname ar eax nelygu 0; po dalybos eax lieka dalmuo jne cs:L_next # jei dar yra ką dalinti eax tai daliname toliau cmp edx, 0 # jei eax = 0; tikriname ar edx = 0, jei abu registrai su reikšme 0, daugiau neliko ką dalinti pereiname į atsakymo spausdinimą je cs:L_writeilgis L_writeilgis: push ecx push eax push edx push esi push ebx mov ecx, 1 mov edx, 0 mov eax,0 mov ebx, [inputmsglen] mov esi, outpliusmsg L_loop: lodsb al, [esi] mov byte ptr [outmsg+ebx], al cmp ecx, 10 je cs:L_exitloop inc ebx inc ecx jmp cs:L_loop L_exitloop: mov [inputmsglen], ebx pop ebx pop esi pop edx pop eax pop ecx mov ecx, [inputmsglen] L_next2: pop [outmsg+ecx] # įkrauname po vieną atsakymo simbolį išsaugota dėkle (stack) į spausdinimo adresą inc ecx dec ebx # mažiname ebx po vienetą, kad žinotume kada baigti spausdinti atsakymo simbolius cmp ebx,0 # tikriname ar ebx = 0; jei ne nulis dar liko simbolių kuriuos reikia atspausdinti jne cs:L_next2 # jei ebx nelygu 0, tai pereiname prie sekančio spausdinamo simbolio mov byte ptr [outmsg+ecx], 0x29 inc ecx mov [inputmsglen], ecx # baigus spausdinti žodžio ilgį, nustatome ecx = 0, kito žodžio ilgiui saugoti push [inputmsglen] push outmsg push 1 mov eax, 4 call cs:_syscall add esp, 12 push 0 mov eax, 1 call cs:_syscall