1. Asemblerio užduotis 1.2 // Aplinka MacOS X + XCode 4 | GNU Assembler

    11Mar26.84reblog

    XCode Project

    #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