二次方程 - 装配 - 使用scanf

时间:2016-04-07 19:32:44

标签: assembly scanf nasm

我正在创建一个汇编程序来解决二次方程。我们的教授给了我们部分代码,但每当我使用我添加的内容运行时,我会使用'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

1 个答案:

答案 0 :(得分:1)

您找不到printf时遇到的问题表明您没有正确链接到 C 库。最简单的方法是更改​​代码以使用入口点main而不是start。更改此代码:

  section .text

    global start

    extern printf, scanf

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

start:

为:

  section .text

    global main

    extern printf, scanf

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

main:

在Linux上,当使用 GCC 链接 C 运行时环境时, C 运行时将提供_start标签执行初始化然后调用函数main

您的代码是32位。如果您使用的是64位Linux,则这些命令应该能够汇编和链接您的代码(将program替换为您的程序名称):

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

如果您使用的是32位Linux,则这些命令应该起作用:

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

在这两种情况下以这种方式运行程序:

./program