通过printf显示浮点 [英] Display floating point by printf

查看:199
本文介绍了通过printf显示浮点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我试图显示一些数学函数的结果,但是我总是得到0.00。



我可以帮助我,告诉我做错了什么?



我的GNU AS代码:

  .text 
text:.ascii函数结果:%4.2f \\\

.data
x:.float 2.0
one:.float 1.0
结果:.float 0.0


格式:.ascii%f


.global主要

主要:
推动$ x
推动$格式
呼叫scanf


FINIT

FLDS x

FMULS x#x * x

FADDS 1

FSQRT

FSUB one

FSTS结果

xor%eax,%eax

$ b push $ result
push $ text
$ b $ call printf

$ b $ pushl $ 0
call exit


解决方案

在GNU汇编中, $ 指定一个文字值进入指令)。标签的值是它的地址。所以 $ x $格式 $结果 $ text 是这些标签的地址;他们是你有标签值的地址。 printf 不会使用%f 的地址。您必须传递浮点数的值,而不是其地址。而且,正如弗兰克·科特勒(Frank Kotler)指出的那样,你必须把它作为一个64位的 double ,而不是32位的 float

最简单的方法是插入 add $ -8,%esp (或<$在$ FSTS结果指令前修改c $ c> add%esp,$ -8 ,取决于汇编器版本中操作数的顺序) FSTS结果指令到 FST(%esp) FSTL(%esp),这取决于你的汇编程序。 (也可以使用 FSTP(%esp) FSTPL(%esp) )然后删除 push $ result



这些更改将分配八个(在 add 指令中)并将浮点结果存储到这八个字节中。



另外,我希望你的代码负责清理传递给被调用例程的参数:在调用 scanf 来弹出两个参数之后,它应该向堆栈指针添加8个字符,在调用 printf 后添加十二个参数,弹出新的八字节参数和格式字符串的四字节地址。由于您通过调用 exit 来终止程序,因此您的程序可能在没有这些更改的情况下运行。但是,如果不清除堆栈,就不可能从 ret 指令的例程返回。



补充



以下代码可在 ideone.com 上使用汇编程序(gcc-4.7.2)的第二个选择:

$ $ $ $ $ $ $ $ $ $ $ $ $文本:.asciz函数结果: %4.2f \\\

.data
x:.float 2.0
one:.float 1.0
结果:.float 0.0


格式:.asciz%f


.global main

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

FINIT

FLDS x

FMULS x#x * x

FADDS一

FSQRT

FSUB一
加$ -8,%esp
FSTPL(%esp)

xor%eax,%eax


push $ text

call printf
add $ 12,%esp


pushl $ 0
退出


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

解决方案

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

这篇关于通过printf显示浮点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆