0

Here in a simple test of NASM floating point operations, i begin gathering data for solving a system of two linear equations. However, the output of the program which should take a1 * a4, is much too long to be sensible. I put in single digit integers as my numbers and still got a result which traverses several console lines. What am i doing wrong?

My code:

extern printf
extern scanf
extern exit

global main

SECTION .data
message1: db "Enter the value of ",0
welcome: db "Welcome to the linear equation solver.",10,10,0

eq1:db "    a1 * x + a2 * y = b1",10,0
eq2:db "    a3 * x + a4 * y = b2",10,10,0

formats: db "%s",0
formatss: db "%s %s: ",0
formatf: db "%f",0
a1: db "a1",0
a2: db "a2",0
a3: db "a3",0
a4: db "a4",0
b1: db "b1",0
b2: db "b2",0

SECTION .bss

float1: resd 1
float2: resd 1
float3: resd 1
float4: resd 1
float5: resd 1
float6: resd 1
a1a4: resd 1
a2a3: resd 1

SECTION .text

main:

;Welcome to the linear equation solver
push welcome
push formats
call printf
add esp, 8

;show equation type
push eq1
push formats
call printf
add esp, 8
push eq2
push formats
call printf
add esp, 8

;get a1
push a1
push message1
push formatss
call printf
add esp, 12
push float1
push formatf
call scanf
add esp, 8

;get a2
push a2
push message1
push formatss
call printf
add esp, 12
push float2
push formatf
call scanf
add esp, 8

;get b1
push b1
push message1
push formatss
call printf
add esp, 12
push float5
push formatf
call scanf
add esp, 8

;get a3
push a3
push message1
push formatss
call printf
add esp, 12
push float3
push formatf
call scanf
add esp, 8

;get a4
push a4
push message1
push formatss
call printf
add esp, 12
push float4
push formatf
call scanf
add esp, 8

;get b2
push b2
push message1
push formatss
call printf
add esp, 12
push float6
push formatf
call scanf
add esp, 8

;Initiate floats
FINIT

;Bring a1 into st float register.
fld dword [float1] ;ST0
fmul dword [float4] ;ST0 *= float4
fstp dword [a1a4] ;Store result: a1 * a4, pop float stack

;print a1 * a4
fld dword [a1a4]
sub esp, 8
fstp qword [esp]
push formatf
call printf
add esp, 12

call exit
Drifter64
  • 1,103
  • 3
  • 11
  • 30
  • Does that even assemble? `fld dword float1` looks like invalid NASM syntax to me. It should be `fld dword [float1]` (same goes for the other floating point instructions). And `push dword a1a4` should be `push dword [a1a4]`. – Michael Oct 18 '13 at 07:55
  • My apologies. To be honest, NASM has me so flipped upside down after knowing MASM that i was trying everything, even if it didn't make sense. This incorrect code you saw DOES compile, it just operates on the memory address instead of the intended value AT that address. I have edited my main code to reflect the changes you suggest. However, the problem still exists in exactly the same manner. – Drifter64 Oct 18 '13 at 14:33
  • And what if you print the contents of `float1` and `float4`? Do they look ok? – Michael Oct 18 '13 at 14:51
  • pushing the contents of float1 to printf returns a similar really long number. My assumption is that the floating point operation is working, but something might be wrong with my scanf. – Drifter64 Oct 18 '13 at 14:56
  • possible duplicate of [Printing floats with printf in x86 nasm 32-bit](http://stackoverflow.com/questions/29442155/printing-floats-with-printf-in-x86-nasm-32-bit) this is older, but the example of the other is more minimal – Ciro Santilli OurBigBook.com May 12 '15 at 06:57

1 Answers1

0

Found the problem! It seems that floats are stored in 80 bits, but in order to print it properly, you have to force it into a 64 bit double representation. I have changed the code accordingly. Here is how you would print any of these numbers stored in memory:

fld dword [a1a4] ;load a1a4 float into FPU
sub esp, 8 ;reserve qword space for this in stack
fstp qword [esp] ;pop into stack
push formatf
call printf
add esp, 12
Drifter64
  • 1,103
  • 3
  • 11
  • 30