ARMv8平台下使用radare2正确打印浮点寄存器值的方法
在ARMv8上用radare2正确查看浮点寄存器值
问题场景
在ARMv8架构机器上使用radare2调试可执行程序时,直接用dr指令查看浮点寄存器会得到错误结果(比如d1寄存器输出异常值),需要用正确方式解析浮点寄存器中的float类型值。
测试案例
测试代码(test.c)
//test.c #include<stdlib.h> #include<stdio.h> int main(void){ float x =1.1f, y = 1.1f, z; z = x+y; return 0; }
编译命令
gcc test.c -o test
调试步骤
>>r2 -AA -d test >>db main >>dc
断点处汇编代码
将PC定位到fadd s0, s1, s0指令处,汇编内容如下:
┌ 64: int main (int64_t argc); │ ; arg int64_t argc @ sp+0x20 │ ; var int64_t var_4h @ sp+0x4 │ ; var int64_t var_8h @ sp+0x8 │ b ff4300d1 sub sp, sp, 0x10 │ a0999952 mov w0, 0xcccd │ 80f1a772 movk w0, 0x3f8c, lsl 16 │ 0000271e fmov s0, w0 │ e00700bd str s0, [sp, 4] │ a0999952 mov w0, 0xcccd │ 80f1a772 movk w0, 0x3f8c, lsl 16 │ 0000271e fmov s0, w0 │ e00b00bd str s0, [sp, 8] │ e10740bd ldr s1, [var_4h] │ e00b40bd ldr s0, [var_8h] │ ;-- pc: │ 2028201e fadd s0, s1, s0
错误输出
执行dr指令后,部分寄存器输出异常:
>>dr //... d0=0x3f8ccccd d1=0x7ff3cbffff //...
问题原因
ARMv8浮点寄存器架构中,32位s寄存器是64位d寄存器的低32位。dr指令默认以64位十六进制格式显示d寄存器,未初始化的高32位会包含随机垃圾数据,导致d1显示异常。而代码中的变量是float类型,对应32位s寄存器,必须指定解析格式才能得到正确值。
解决方法
使用radare2的dr指令配合格式参数,指定以32位浮点类型解析寄存器:
查看所有浮点寄存器的浮点值:
dr f该命令会自动区分32/64位类型,将所有浮点寄存器解析为对应浮点数值。
查看单个32位浮点寄存器的值:
- 直接指定
s寄存器并添加格式:dr s0.f32 dr s1.f32 - 或通过
d寄存器的低32位解析:dr d0.f32 dr d1.f32
执行后会输出正确浮点值,比如
1.100000023841858(符合float的精度特性)。- 直接指定
查看64位浮点寄存器(double类型):
如果需要查看double类型的值,使用.f64格式:dr d0.f64
验证结果
在当前断点处执行dr s0.f32和dr s1.f32,会得到与代码中1.1f对应的浮点值,说明解析正确。
内容的提问来源于stack exchange,提问作者XuezhuJiang
相关产品推荐
相关产品推荐

