Display floating point by printf

≯℡__Kan透↙ 提交于 2019-12-13 04:21:27

问题


I have problem with display floating point value using printf.

I'm trying display result of some math function, but I always get 0.00.

Could you help me and tell what I'm doing wrong?

My GNU AS code:

.text
text: .ascii  "Function result: %4.2f \n"
.data
x: .float 2.0
one: .float 1.0
result: .float 0.0


format: .ascii "%f"


.global main

main:
push $x
push $format
call scanf


FINIT

FLDS x  

FMULS x     #x*x

FADDS one   

FSQRT       

FSUB one        

FSTS result

xor %eax, %eax


push $result
push $text

call printf


pushl $0
call exit

回答1:


In the GNU assembler, $ designates a literal value (a value that is encoded into the instruction). The value of a label is its address. So $x, $format, $result, and $text are the addresses of those labels; they are the addresses where you have the values you are labeling. printf does not use an address for %f. You must pass the value of the floating-point number, not its address. And, as Frank Kotler notes, you must pass it as a 64-bit double, not a 32-bit float.

The easiest way to do this might be to insert add $-8, %esp (or add %esp, $-8, depending on the order of operands in your assembler version) before the FSTS result instruction and change the FSTS result instruction to either FST (%esp) or FSTL (%esp), depending on your assembler. (Also, these could be FSTP (%esp) or FSTPL (%esp) to pop the value from the floating-point stack instead of leaving it there.) Then delete the push $result.

These changes will allocate eight bytes on the stack (in the add instruction) and store the floating-point result to those eight bytes.

Also, I expect your code is responsible for cleaning up arguments passed to called routines: It should add eight to the stack pointer after calling scanf to pop the two arguments, and it should add twelve after calling printf to pop the new eight-byte argument and the four-byte address of the format string. Your program may work without these changes since you terminate the program by calling exit. However, it would not be possible to return from a routine with the ret instruction without cleaning up the stack.

Supplement

The following code works at ideone.com, using the second choice for Assembler (gcc-4.7.2):

.text
text: .asciz  "Function result: %4.2f \n"
.data
x: .float 2.0
one: .float 1.0
result: .float 0.0


format: .asciz "%f"


.global main

main:
push $x
push $format
call scanf
add $8, %esp

FINIT

FLDS x  

FMULS x     #x*x

FADDS one   

FSQRT       

FSUB one        
add $-8, %esp
FSTPL (%esp)

xor %eax, %eax


push $text

call printf
add $12, %esp


pushl $0
call exit


来源:https://stackoverflow.com/questions/16629805/display-floating-point-by-printf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!