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

ARM汇编实现IEEE 754软浮点加法算法结果异常求助

ARM汇编实现IEEE 754浮点加法异常问题

测试场景:计算1.0 + 1.0,程序执行到BX lr时,预期R0寄存器值为0x40000000(对应IEEE 754单精度的2.0),但实际得到0x40800000(对应4.0)。

编译命令

arm-none-eabi-as -g -o float.o float.s
arm-none-eabi-ld -o float float.o

运行与调试方式

  • 用Qemu运行:
qemu-arm -g 30005 ./part5
  • 远程调试:
gdb-multiarch file ./float target remote:30005

采用常规单步调试方式。

汇编代码

.section .data

@ Constants
exponent_mask: .word 0x7F800000

@ The two numbers we want to add
num1:   .word   0x3f800000
num2:   .word   0x3f800000 

.section .text
.global main

main:
@ Load numbers directly
    LDR r0, =num1
    LDR r0, [r0]
    LDR r1, =num2
    LDR r1, [r1]

@ Load constant for exponent extraction just once
    LDR r12, =exponent_mask
    LDR r12, [r12]

@ Extract exponents
    AND r2, r0, r12
    AND r3, r1, r12
    LSR r2, r2, #23
    LSR r3, r3, #23

@ Clear the exponent parts
    BIC r4, r0, r12
    BIC r5, r1, r12

@ Add the implicit 1 to the fractions
    ORR r4, r4, #0x00800000  
    ORR r5, r5, #0x00800000  

@ Align exponents and adjust fractions
    CMP r2, r3
    BGT largerExponent

@ r3 has larger exponent
    SUB r6, r3, r2
    LSR r4, r4, r6
    MOV r2, r3
    B fractionsAligned

largerExponent:
    SUB r6, r2, r3
    LSR r5, r5, r6

fractionsAligned:
    ADD r4, r4, r5   @ Add aligned fractions

@ Normalize if needed
    TST r4, #0x01000000
    BEQ doneNormalize
    LSR r4, r4, #1
    ADD r2, r2, #1

doneNormalize:
    @ Construct the final number
    LSL r2, r2, #23
    ORR r0, r4, r2

BX lr

问题根源分析

问题出在分数相加后的归一化步骤:

  1. 1.0的IEEE 754单精度表示为0x3F800000,指数为0x7F(偏移后的值,实际指数为0),分数部分为0;加上隐式1后,分数变为0x00800000。
  2. 两个数相加后r4 = 0x00800000 + 0x00800000 = 0x01000000。
  3. 代码检测到该值的第24位为1,执行右移1位得到0x00800000,同时指数加1变为0x80。
  4. 此时r4仍保留了隐式1的位(0x00800000),但IEEE 754规格化数的隐式1是不存储在分数字段中的,最终构造结果时,这个位被错误地当成显式分数位,与左移后的指数位(0x80<<23 = 0x40000000)或操作,得到0x40800000。

修复方案

在归一化步骤结束后,清除分数中的隐式1位,修改后的归一化及结果构造代码如下:

@ Normalize if needed
    TST r4, #0x01000000
    BEQ doneNormalize
    LSR r4, r4, #1
    ADD r2, r2, #1

doneNormalize:
    @ 移除隐式1位,IEEE754规格化数不存储该位
    BIC r4, r4, #0x00800000  @ 新增该行代码

    @ Construct the final number
    LSL r2, r2, #23
    ORR r0, r4, r2

修复后验证

修改后计算流程:

  • 相加后r4=0x01000000,归一化后r4=0x00800000,指数r2=0x80。
  • 执行BIC指令后,r4=0x00000000。
  • 最终r0 = 0x40000000 | 0x00000000 = 0x40000000,符合预期的2.0。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 04:32:54