User Tools

Site Tools


isu:cv12

[ISU] 12. FPU - porovnávání

cv12_A.asm ukázka

cv12_A.asm
%include "rw32.inc"
CEXTERN printf
 
section .data
    x     dq  123456789.9876
    f_str db  "%.3f",0
section .text
vlastniFloat32:
    enter 0,0
    push __float32__(42.9) ; vloží 32b číslo na vrchol zásobníku
    fld dword[esp]         ; načte 32b číslo z vrcholu zásobníku
    add esp, 4             ; smazání čísla
    leave
    ret
 
cisloDouble64:
    enter 0,0
    push dword [x+4] ; dolní část čísla
    push dword [x]   ; horní část čísla
    fld qword [esp]  ; load z vrcholu zásobníku
    fsin             ; libovolná operace (sin)
    fstp qword [esp] ; uložení 64bit čísla do zásobníku
    push f_str       ; argument pro printf
    call printf      ; zavolání externí C funkce
    call WriteNewLine
    leave
    ret
 
eaxToSt0:
    enter 0,0
    call ReadFloatNewLine ; uživatelská hodnota do EAX (float ale int)
    push eax         ; EAX do zásobníku
    fld dword [esp]  ; načtení z vrcholu zásobníku do ST0
    add esp, 4       ; úklid
    call WriteDoubleNewLine ; vypsání ST0
    leave
    ret
 
st0ToEax:
    enter 0,0
    sub esp, 4        ; alokace lokální proměnné
    call ReadDoubleNewLine ; načtení uživatelské 64b hodnoty
    fst dword [ebp-4] ; ulož 32 číslo z ST0 do lokální proměnné
    mov eax, [ebp-4]  ; zkopíruj hodnotu z lokální promměné do EAX
    call WriteFloatNewLine ; výpis 32b float hodnoty z EAX
    add esp, 4        ; úklid
    leave
    ret
 
main:
    enter 0,0
    call vlastniFloat32
    call cisloDouble64
    call eaxToSt0
    call st0ToEax
    leave
    ret

cv12_1.asm

cv12_1.asm
%include "rw32.inc"
section .text
objem:
    ; Napiš funkci pro výpočet objemu kuželu
    ; Výsledek zanech v EAX, fpu registry prázdné.
    ret
 
main:
    enter 0,0
    push __float32__(20.5)  ; v
    push __float32__(12.34) ; r
    call objem       ; float objem(float r, float v);
    add esp, 8       ; odstraň předané argumenty
    call WriteFloat  ; => 3268.98413 (nebo 3268.98411)
    leave
    ret

cv12_1.asm jedno z mnoha řešení

cv12_1.asm jedno z mnoha řešení

cv12_1.asm
; Napiš funkci pro výpočet objemu kuželu
%include "rw32.inc"
section .text
objem:
    push ebp
    mov ebp, esp
    sub esp, 4    ; alokuj lokální proměnnou
 
    fld dword [ebp+12] ; v
    fld dword [ebp+8]  ; r
 
    ; V = 1/3 * pi * r^2 * v
    fmul st0, st0  ; r^2
    fmulp st1      ; r^2 * v
    fldpi          ; load pi
    fmulp st1      ; *pi
 
    fld1   ; vytvoř 1/3
    fld1
    fadd st1
    fadd st1
    fdivp st1
 
    fmulp st1
 
    fstp dword [ebp-4] ; ulož st0 do lokální proměnné (zásobníku)
    mov eax, [ebp-4]   ; ze zasobníku (lok prom) to EAX
 
    mov esp, ebp
    pop ebp
    ret
 
main:
    enter 0,0
    push __float32__(20.5)  ; v
    push __float32__(12.34) ; r
    call objem   ; float objem(float v, float r);
    add esp, 8   ; odstraň předané argumenty
    call WriteFloat   ; => 3268.98413
    leave
    ret


cv12_B.asm ukázka

cv12_B.asm
; Ukázka porovnání a jump
%include "rw32.inc"
section .data
    a    dd  15.5
    b    dd  10.0
section .text
main:
    fld dword [a]
    fld dword [b]
    fcomi st1 ; vyzkoušej:  fcomi  a  fcompp
    ja above  ; ST0 > ST1
    jb below  ; ST0 < ST1
    je equal  ; ST0 == ST1
    jp problem ; error, např. NaN > 0
above:
    mov eax, 1
    jmp end
below:
    mov eax, 2
    jmp end
equal:
    mov eax, 3
    jmp end
problem:
    mov eax, 4
    jmp end
end:
    call WriteInt32
    ret

cv12_C.asm ukázka

cv12_C.asm
; Ukázka druhů porovnání
%include "rw32.inc"
section .data
    a    dd  15.5
section .text
main:
    fld dword [a]
 
varianta_1:
    ftst     ; porovnej ST0 a 0.0
    fstsw ax ; ulož status word do AX
    sahf     ; ulož AH do EFLAGS -> nastavení ZF, PF, CF
    jz st0_is_zero
varianta_2:
    fldz     ; načti 0.0 do ST0
    fcomp    ; porovnej ST0 (=0.0) a ST1 -> nastavení C3, C2, C0 příznaků
    fstsw ax ; ulož status word do AX
    sahf     ; ulož AH do EFLAGS -> nastavení ZF, PF, CF
    jz st0_is_zero
varianta_3:
    fldz     ; načti 0.0 do ST0
    fcomip   ; porovnej ST0 (=0.0) a ST1 -> nastavení ZF, CF, PF příznaků v EFLAGS
    jz st0_is_zero
 
st0_is_zero:
    ret

cv12_2.asm

cv12_2.asm
%include "rw32.inc"
section .data
    pole   dd    42.4, 456.78, 884.1, 12.45, 94.0, 22.2
    n      dd    6
 
section .text
main:
    ; Vypiš největší číslo z pole
 
end:
    call WriteDouble
    ret

cv12_2.asm jedno z mnoha řešení

cv12_2.asm jedno z mnoha řešení

cv12_2.asm
%include "rw32.inc"
section .data
    pole   dd    42.4, 456.78, 884.1, 12.45, 94.0, 22.2
    n      dd    6
 
section .text
main:
    mov ecx, [n]
    fldz   ; prvni maximum
.cyclus:
    fld dword [pole + (ecx-1) * 4]
    fcomi st1
    jb .skip  ; st0 < st1 => skip
    fxch st0, st1  ; prohozeni
.skip:
    fcomp  ; just pop
    loop .cyclus
end:
    call WriteDouble
    ret


cv12_3.asm

cv12_3.asm
; V předchozím příkladu cv12_2 změň datový typ pole dd -> dq a uprav kód
pole   dq    42.4, 456.78, 884.1, 12.45, 94.0, 22.2

cv12_3.asm jedno z mnoha řešení

cv12_3.asm jedno z mnoha řešení

cv12_3.asm
; změna pouze na řádku načtení
fld qword [pole + (ecx-1) * 8]


cv12_4.asm

cv12_4.asm
; Součet čísel v poli menších než zadané číslo X.
%include "rw32.inc"
section .data
    pole  dd  1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8
    size  dd  8
 
section .text
main:
    enter 0,0
    call ReadDouble
 
 
    leave
    ret

cv12_5.asm

cv12_5.asm
; Definuj si pole s alespoň 5 float čísly (dd)
; Proveď sort tohoto pole (seřazení od nejmenšího po největší)

isu/cv12.txt · Last modified: 2024/04/25 19:36 by sakin