User Tools

Site Tools


isu:cv09

[ISU] 9. Volání funkcí jazyka C

cv9_A.asm ukázka

cv9_A.asm
; ukázka lokální proměnné
%include "rw32.inc"
 
section .text
fce:
    push eax     ; záloha registru A
    push ebp     ; zálohuj staré dno
    mov ebp, esp ; vytvoř nové dno
    sub esp, 12  ; rezervuj 3 lokální proměnné
 
    mov [ebp - 3*4], dword 5 ; vložení do lokální proměnné
    mov [ebp - 2*4], dword 10
 
    mov eax, [ebp - 2*4]  ; vyčtení
    add eax, [ebp - 3*4]
    mov [ebp - 1*4], eax
    call WriteInt32NewLine
 
    mov esp, ebp ; smazání proměnných
    pop ebp      ; obnova starého dna
    pop eax      ; obnova registru A
    ret
 
main:
    push ebp
    mov ebp, esp
 
    mov eax, 123 ; bude zachovano
    call fce
 
    pop ebp
    ret

cv9_B.asm ukázka

cv9_B.asm
; ukázka řetězových instrukcí
%include "rw32.inc"
section .data
    string1 db "Ahoj",0
    string2 db "xxxx",0
    src db "Hello world!",0
    dst db "xxxxx xxxxxx",0
 
section .text
main:
    ; == MOVS ==
    mov esi, string1
    mov edi, string2
    movsb ; Výsledek ve string2: "Axxx"
    movsb ; Výsledek ve string2: "Ahxx"
    movsb ; Výsledek ve string2: "Ahox"
    mov esi, string2
    call WriteStringASCIIZNewLine
 
    ; == STOS a LODS ==
    mov edi, string2
    mov al, 'B'
    stosb   ; výsledek string2: "Bxxx"
    stosb   ; výsledek string2: "BBxx"
    stosb   ; výsledek string2: "BBBx"
    mov esi, string2
    call WriteStringASCIIZNewLine
 
    mov esi, string1
    lodsb   ; v AL symbol "A"
    call WriteCharNewLine
 
    ; == REP ==
    mov esi, src ; ESI = zdroj
    mov edi, dst ; EDI = cíl
    mov ecx, 5   ; ECX = počet
    cld          ; DF = 0 (doprava)
    ; zkopiruj 8b, ECX--, opakuj dokud ECX != 0
    rep movsb
    ; Vypiš
    mov esi, dst
    call WriteStringASCIIZNewLine
    ret

cv9_1.asm

cv9_1.asm
; Vytvoř funkci, která od uživatele načte jeden znak,
; najde jeho první výskyt v řetězci "string"
; a nahradí v poli pomlčkou. Vypiš upravený řetezec.
; Využíj řetězové instrukce.
; H  ==>  -ello world!
; o  ==>  Hell- world!
 
%include "rw32.inc"
section .data
    string db "Hello world!",0
    len    db 12
 
section .text
fce:
 
    ret
 
main:
 
    ret

cv9_1.asm jedno z mnoha řešení

cv9_1.asm jedno z mnoha řešení

cv9_1.asm
%include "rw32.inc"
section .data
    string db "Hello world!",0
    len    db 12
 
section .text
fce:
    push ebp
    mov ebp, esp
 
    xor eax, eax
    xor ecx, ecx
    mov cl, [len]
    mov edi, string
    call ReadCharSilent ; -> AL
 
.loop:
    scasb  ; porovná AL se znakem v EDI, EDI++
    je .found
    loop .loop
    jmp .endfce
 
.found:
    mov al, '-'
    dec edi ; protože scasb už udělal posun
    stosb   ; uloží hodnotu z AL do řetězce v EDI
 
.endfce:
    mov esp, ebp
    pop ebp
    ret
 
main:
    call fce
    mov esi, string
    call WriteStringASCIIZNewLine
    ret


cv9_C.asm ukázka

cv9_C.asm
; Volání externí funkce printf() z Céčka
%include "rw32.inc"
 
CEXTERN printf  ; nebo: extern printf
 
section .data
    sFormat db "Printed by printf() string = %s, A = %d, B = %d, C = %d", 0
          x dd -56
sSomeString db "some string",0
 
section .text
main:
    enter 0,0
    mov eax,100
 
    ; printf(sFormat, "some string", 5, x, 100);
    push eax   ; 100
    push dword [x]
    push 5
    push sSomeString ; -> "some string",0
    push sFormat
    call printf
 
    add esp, 5*4 ; volající uklízí
    ;mov esp, ebp  - stejný efekt uklizení
 
    leave
    ret

cv9_2.asm

cv9_2.asm
; Napiš funkci "ObratRetez", která dostane jako argumenty
; ukazatel na pole znaků (řetezec) a počet znaků N.
;   char* ObratRetez(char* string, int N);
; Konvence volání: pascal
; Využívej lokální proměnné (zásobník), registry musí mít po ukončení funkce původní hodnoty.
; Výsledkem funkce bude převrácené pořadí znaků v proměnné string.
;
; ReadString:
; * potřeba nastavit EDI (kam uložit načtené znaky)
; * počet načtených symbolů v EAX
 
%include "rw32.inc"
section .bss
    string resd 50 ; zde ulož načtený řetězec
 
section .text
ObratRetez:
    ; todo
    ret
 
main:
    xor eax, eax
    mov edi, string
    call ReadStringSilent ; načte řetezec, N je v ECX
 
    ; todo
    call ObratRetez
 
    ; Vypsání převráceného řetězce
    mov esi, string
    call WriteStringASCIIZNewLine
    ret

cv9_2.asm jedno z mnoha řešení

cv9_2.asm jedno z mnoha řešení

cv9_2.asm
%include "rw32.inc"
section .bss
    string resd 50 ; zde ulož načtený řetězec
 
section .text
; char* ObratRetez(char* string, int N);
ObratRetez:
    enter 0,0
    push eax   ; záloha ragistru z main
    mov ecx, [ebp + 8]  ; vyčtení arg N
    mov esi, [ebp + 12] ; vyčtení arg *string
 
.doZasobniku:
    xor eax, eax
    mov al, [esi + ecx-1]
    push eax
    loop .doZasobniku
 
    mov ecx, [ebp + 8]  ; N
.zeZesobniku:
    pop eax
    mov [esi + ecx-1], al
    loop .zeZesobniku
 
    pop eax  ; obnova původních hodnot main
    leave
    ret 8  ; uklizení argumentů ze zásobníku (2*4)
 
main:
    xor eax, eax
    mov edi, string
    call ReadStringSilent ; načte řetezec, N je v ECX
 
    ; konvence pascal
    push string
    push eax    ; N
    call ObratRetez
 
    ; Vypsání převráceného řetězce
    mov esi, string
    call WriteStringASCIIZNewLine
    ret


cv9_3.asm

cv9_3.asm
; Vyzkoušej libovolnou funkci: strlen, strcmp, strstr, qsort, malloc, free

isu/cv09.txt · Last modified: 2025/04/17 10:19 by sakin