0

I am creating an assembly program to solve a quadratic equation. Our professor gave us part of the code, but whenever I run hers with what I've added, I get an error using 'scanf'. it says undefined reference to printf and also undefined reference to scanf. Im not sure how to just create different code that would be equivelant to scanf and printf instead of calling them, I feel that would be easier and work.

  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
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Elizabeth
  • 13
  • 1
  • 7
  • Are you linking it against the standard library? Also, there's no way I'm looking at that mass of assembly code with no indenture and no comments. – David Hoelzer Apr 07 '16 at 19:37
  • -I am super new at assembly. what does it mean to link it to the standard library? At the top of the code, I put extern scanf...is that what you mean? – Elizabeth Apr 07 '16 at 19:43
  • 1
    What commands are you using to assemble and link? And on what platform? – Peter Cordes Apr 07 '16 at 20:14
  • Peter is asking what commands you use to build your program. For instance using nasm could look something like `nasm -felf32 program.asm -o program.o` (we'd like to know what command you are actually using). There would be a second step that would use `gcc` or `ld` to generate the final executable. We'd like to know the command you use to do that part. – Michael Petch Apr 07 '16 at 20:22
  • I have a hunch you might doing something like `nasm -felf32 program.asm -o program.o` followed by a command like `ld -melf_i386 program.o -o program -e _start` . I suspect you are at least using _LD_ to do the last part because it is one of the few ways on Linux (Are you using Linux?) that I could see you getting this error. Update your question with the commands you use, and someone should be able to help you. – Michael Petch Apr 07 '16 at 20:26

1 Answers1

1

The issue you are having with printf not being found suggests that you aren't properly linking to the C library. The easiest way to make this work is to change your code to use the entry point main instead of start. Change this code:

  section .text

    global start

    extern printf, scanf

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

start:

to:

  section .text

    global main

    extern printf, scanf

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

main:

On Linux, when using GCC to link against the C runtime environment, the C runtime will provide a _start label that performs initialization and then calls your function main.

Your code is 32-bit. If you are on 64-bit Linux these commands should be able to assemble and link your code (replace program with the name of your program):

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

If you are on a 32-bit Linux these commands should work:

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

To run the program in both cases is done this way:

./program
Michael Petch
  • 46,082
  • 8
  • 107
  • 198