You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARM64架构下通过scanf读取浮点值后打印异常的问题排查求助

问题分析与解决方案

你的问题出在scanf格式符和变量类型不匹配,以及ARM64架构下浮点类型的存储/读取规则上,咱们一步步拆解:

核心问题:scanf的格式符与变量类型不匹配

在遵循C调用约定的汇编代码中,scanf的格式符和变量类型有严格对应:

  • scanf("%f") 用于读取4字节float类型的值,要求传入float*指针;
  • 你的value定义为.double 0,是8字节的double类型,用%f去读写double变量时,只会写入前4字节,剩下的4字节保留初始值0,最终整个double变量的数值完全错误。

而printf的%f可以兼容float或double(因为float会被自动提升为double),但当你用ldr d0, [x1]读取这个被错误写入的double变量时,得到的是拼接了无效高4字节的错误值,自然打印异常。

修复方案

只需要把输入格式符改成%lf(对应8字节double类型的读取),修改你的.data段中的input_fmt:

input_fmt: .asciz "%lf"

修改后的完整代码如下:

// print_a_float_2.s
.global main
.extern scanf
.extern printf
.section .data
input_str: .asciz "Input a float: "
input_fmt: .asciz "%lf"  // 这里改成%lf
value: .double 0
output_str: .asciz "You entered %f.\n"
.section .text
main:
// Prolog
stp x29, x30, [sp, -16]!
mov x29, sp
// Get value from user
ldr x0, =input_str
bl printf
ldr x0, =input_fmt
ldr x1, =value
bl scanf
print:
// Now print value
ldr x0, =output_str
ldr x1, =value
ldr d0, [x1]
bl printf
// Cleanup
mov x0, #0
ldp x29, x30, [sp], 16
ret

关于你调试时的疑惑解释

你提到调试时看到value中存储了正确的1.2345,但d0里的值不对——这大概率是因为调试器默认用float格式解析了value的前4字节,而实际它是一个double类型变量。当你用ldr d0, [x1]读取完整的8字节时,高4字节的0会被解析成double的指数部分,导致最终数值完全偏离预期。

内容的提问来源于stack exchange,提问作者Andrew H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 12:24:07