2016-04-02 50 views
0

Gelecek hafta yaklaşan bir projem var ve son 2 gün boyunca bir nth kökü nasıl yapacağımı anladım.x86 Montaj (NASM) Neyin kökle kalacağı veya kayan nokta değeri nasıl artırılacağı

Montaj NASM'de Geometrik Ortalama'u simüle etmem gerekiyor.

FPU'nun Square Rooting için bir talimatı olduğunu biliyorum, ancak bu beni gerçekten fazla uzaklamayacak.

Şu anda, istediğim kadar girdi girebiliyorum ve bunları hiçbir sorun olmadan çarpar. Ancak NASM ile nasıl yapılacağını bilmediğim için 'nth root' kısmına takılıyorum.

Bu benim şimdiki kodudur:

global _main 
    extern _printf, _scanf, _system 

    section .text 

    _main: 
    mov ebp, esp; for correct debugging 
push clr 
call _system 
add esp, 4 

    ; start of INITIALIZE 
    ;printf("Enter number of elements") 
push print1 
call _printf 
add esp, 4 
    ; scanf number of elements 
push n 
push scan1 
call _scanf 
add esp, 8 

    ; printf("enter n integers") 
    push dword [n] 
push print2 
call _printf 
add esp, 8 

    fld qword [n2] 


    ; scan first element 
    push n2 
    push scan2 
    call _scanf 
    add esp, 8 

    fld qword [n2] 

    JE J1 

    MOV EBX, 1 

    CMP EBX, [n] 
    JE J1 

    L1: 

    push n2 
    push scan2 
    call _scanf 
    add esp, 8 

    fld qword [n2] 
    fmul st1, st0 
    fstp qword [ans] 

    INC EBX 
    CMP EBX, dword [n] 
    JE J1 
    LOOP L1 

    J1: 

    fst qword [ans] 

    push dword [ans+4] 
    push dword [ans] 
    push print3 
    call _printf 
    add esp, 12 

    mov dword [data8], n 

    fld qword [data7] 
    fld qword [data8] 

    fdiv st1, st0 

    fstp qword [ans] 


    fst qword [ans] 

    push dword [ans+4] 
    push dword [ans] 
    push print3 
    call _printf 
    add esp, 12 

    xor eax, eax 
    ret 

    section .data 
    clr  db "cls", 0 
    print1 db "Enter the number of elements:", 13,10,0 
    scan1 db "%d" , 0 
    scan2 db "%lf" , 0 
    n  dd 0 
    n2  dq 0.0 
    n3  dq 0.0 
    print2 db "Enter %d values:", 13,10,0 
    print3 db "Value is %g", 13, 10,0 
    data8 dq 3.0 
    ans  dq 0.0 
    loopstart dq 1.0 
    data7 dq 1.0 

Ya da bir n'inci kök ayıklanması için harici C işlevi kullanmak da mümkündür?

DÜZENLEME: C'den _pow'u kullanmaya çalışıyorum. Bu kodu aldım ama çalışmıyor, birisi yardımcı olabilir mi? POW için (C), bu Amaçlı

 LEA ESI, [return] 

     push ESI 
     push dword [pushingthing+4] 
     push dword [pushingthing] 
     push dword [ans+4] 
     push dword [ans] 
     push pow1 
     call _pow 
     add esp, 24 

     section .data 

     return dq 0.0 
     pushingthing dq 2.0 
     pow1  dd "%g, %g", 13, 10, 0 

iki çift pow (x, y) 'in bir biçimi vardır ve bir çift değer geri gönderir. Lütfen kontrol edin.

+0

Elbette, 'n'-kökünün' 1/n' için güçle aynı olduğunu bilerek C 'pow' işlevini kullanabilirsiniz. Montajda, logaritma kullanabilirsiniz. – Jester

+0

Kayan nokta değerlerini dönüş değeri olan bir C işlevine nasıl aktaracağımı hala bilmiyorum. Bana öğretmen mümkün mü? Bir çözüm için internette araştırıyorum ama güldüm. –

+0

Bu, platformunuz için çağrı kuralında açıklanmıştır (bahsetmediniz). Genellikle cpu yığınında giriş argümanlarını geçirir ve sonucu 'st (0) 'olarak geri alırsınız. – Jester

cevap

4

push'u kullanarak bağımsız değişkenleri iletmek için, özellikle de çiftler, başınızı tüm geri dönüş ve yarıya düşürecektir :) Yalnızca alan ayırmanız ve uygun mov yönergelerini kullanmanız gerekir. Hala hangi ortamda olduğunuzu söylemediniz, ancak çoğu geri dönüş st(0) (yani kayan nokta yığını) ile sonuçlanır. Bu şekilde bir örnek:

sub esp, 16   ; space for 2 doubles 
fld qword [x]  ; load 1st arg 
fstp qword [esp]  ; write to stack 
fld qword [y]  ; load 2nd arg 
fstp qword [esp+8] ; write to stack 
call _pow 
; result is now in st(0) print it 
mov dword [esp], fmt ; format string 
fstp qword [esp+4] ; pass result as arg 
call _printf 
add esp, 16   ; free stack space 

x: dq 16.0 
y: dq 0.25 
fmt: db "%g", 13, 10, 0 
+0

Kutsal moly çalışır. Teşekkür ederim ve şu an gizemi kurtarıyorsun. –