2016-04-07 19 views
0

İkinci dereceden bir denklemi çözmek için bir derleme programı oluşturuyorum. Profesörümüz bize kodun bir parçasını verdi, ama ne eklediğimde onu çalıştırdığımda, 'scanf' kullanarak bir hata alıyorum. printf'e tanımlanmamış referans ve scanf için tanımlanmamış referans diyor. Ben sadece onları çağırmak yerine scanf ve printf için eşitleyici olacak farklı bir kod nasıl oluşturulacağından emin değilim, bunun daha kolay olacağını ve çalışacağını hissediyorum.İkinci dereceden denklem- Assembly-scanf kullanarak scanf

section .text 

    global start 



    extern printf, scanf 

    print: 
    mov eax,4 
    mov ebx,1 
    int 0x80 
ret 

start: 

mov ecx, a1 
mov edx, la1 
call print 

push a 
push scan 
call scanf 

mov ecx,b1 
mov edx,lb1 
call print 

push b 
push scan 
call scanf 

mov ecx,c1 
mov edx,lc1 
call print 

push c 
push scan 
call scanf 

fld qword[b] 
fmul st0 
fld qword[a] 
fmul qword[c] 
mov word[const],4 
fimul word[const] 
fchs 
fadd st1 
fst qword[disc] 

push dword[disc+4] 
push dword[disc] 
push dis 
call printf 

ftst 
fstsw ax 
sahf 
ja real_roots 
sahf 
je one_root 

imag_roots: 
fchs 
fsqrt 
fld qword[b] 
fchs 
fadd st1 
fdiv st1 
fstp qword[x1] 
fld qword[disc] 
fchs 
fsqrt 
fld qword[b] 
fadd st1 
fchs 
fld qword[a] 
mov word[const],2 
fimul word[const] 
fxch st1 
fdiv st1 
fstp qword[x2] 

push dword[x2+4] 
push dword[x2] 
push dword[x1+4] 
push dword[x1] 
push imagroot 
call printf 
jmp over 

real_roots: 
fsqrt 
fld qword[b] 
fchs 
fadd st1 
fld qword[a] 
mov word[const],2 
fimul word[const] 
fxch st1 
fdiv st1 
fstp qword[x1] 
fld qword[disc] 
fsqrt 
fld qword[b] 
fadd st1 
fchs 
fld qword[a] 
mov word[const],2 
fimul word[const] 
fxch st1 
fdiv st1 
fstp qword[x2] 

push dword[x2+4] 
push dword[x2] 
push dword[x1+4] 
push dword[x1] 
push realroot 
call printf 

jmp over 

one_root: 
fsqrt 
fld qword[b] 
fchs 
fadd st1 
fld qword[a] 
mov word[const],2 
fimul word[const] 
fxch st1 
fdiv st1 
fstp qword[x1] 


push dword[x1+4] 
push dword[x1] 
push oneroot 
call printf 

over: 
mov eax, 1 
mov ebx, 0 
int 0x80 

section .bss 
x1 resq 1 
x2 resq 1 
const resw 1 
a resq 1 
b resq 1 
c resq 1 
disc resq 1 

section .data 
scan db "%lf",0 
oneroot db "Root = %f",10,0 
realroot db "Root 1 = %f & Root 2 = %f",10,0 
imagroot db "Root 1 = %fi & Root 2 = %fi",10,0 
dis db "Discriminant = %f",10,0 

a1 db 3 
la1 equ $-a1 
b1 db 3 
lb1 equ $-b1 
c1 db 3 
lc1 equ $-c1 
+0

standart kütüphaneye karşı bağlayarak Are: her iki durumda da

nasm program.asm -o program.o gcc program.o -o program 

programını çalıştırmak için bu şekilde yapılır? Ayrıca, hiçbir montaj ve yorum içermeyen montaj kodu kitlesine bakmanın bir yolu yok. –

+0

-Montajda süper yeniim. standart kütüphaneye bağlamak ne anlama geliyor? Kodun üstünde, extern scanf koyuyorum ... demek istediğin şey bu mu? – Elizabeth

+1

Montaj ve bağlantı yapmak için hangi komutları kullanıyorsunuz? Ve hangi platformda? –

cevap

1

Bulduğunuz olmamak printf ile yaşıyorsanız sorun düzgün C kütüphaneye bağlamak olmadığını düşündürmektedir. Bu çalışmayı yapmanın en kolay yolu, kodunuzuyerine main giriş noktasını kullanmaktır.

section .text 

    global start 

    extern printf, scanf 

    print: 
    mov eax,4 
    mov ebx,1 
    int 0x80 
ret 

start: 

için: Bu kodu değiştirin

Linux, Açık
section .text 

    global main 

    extern printf, scanf 

    print: 
    mov eax,4 
    mov ebx,1 
    int 0x80 
ret 

main: 

C zamanı ortamına karşı bağlamak için GCC kullanılarak C çalışma zamanı gerçekleştiren bir _start etiketi sağlayacaktır başlatma ve sonra işlevinizi main çağırır.

Kodunuz 32 bittir. Eğer 32 bit Linux üzerinde ise

nasm -felf32 program.asm -o program.o 
gcc -m32 program.o -o program 

bu komutlar çalışması gerekir: Eğer 64 bit Linux üzerinde ise bu komutlar kodunuzu (programın adı ile program değiştirin) monte etmek ve bağlamak mümkün olmalıdır :

./program