2016-04-07 13 views
0

私は二次方程式を解くためのアセンブリプログラムを作成しています。私たちの教授は私たちにコードの一部を与えましたが、私が追加したものを使って彼を実行するときはいつでも、私は 'scanf'を使ってエラーになります。それはprintfへの未定義参照とscanfへの未定義参照を示しています。私はscanfとprintfに匹敵する異なるコードをどのように作成するのかよくわかりませんが、呼び出すのではなく、簡単で作業が楽だと思います。二次方程式 - アセンブリを使用してスキャンする

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

あなたは、標準ライブラリに対してそれをリンクしていますか?また、私はアセンブリコードのその大量を、保証やコメントなしで見ているわけではありません。 –

+0

- 私は組立時にスーパー新品です。それを標準ライブラリにリンクすることはどういう意味ですか?コードの先頭に、私はextern scanfを入れます...それはあなたが意味するものですか? – Elizabeth

+1

組み立てとリンクにはどのようなコマンドを使用していますか?どのプラットフォームで? –

答えて

1

あなたが見つからないprintfで抱えている問題は、あなたが適切Cライブラリにリンクされていないことを示唆しています。この作業を行う最も簡単な方法は、startの代わりにエントリポイントmainを使用するようにコードを変更することです。 Cランタイム環境にリンクするGCCを使用した場合、Cランタイムが実行_startラベルを提供します、

Linuxの
section .text 

    global main 

    extern printf, scanf 

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

main: 

:に

section .text 

    global start 

    extern printf, scanf 

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

start: 

:このコードを変更次に、関数mainを呼び出します。

コードは32ビットです。あなたは32ビットLinux上にある場合

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

これらのコマンドが動作するはずです:あなたは64ビットLinux上にある場合、これらのコマンドは、あなたのコード(プログラムの名前でprogramを置き換え)をアセンブル、リンクすることができるはずです:

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

両方のケースでは、プログラムを実行するには、この方法で行われます:

./program 
関連する問題