如何将无符号64位整数转为浮点数?x86汇编实现方案咨询
无符号64位整数转double的x86汇编实现(无VCVTUSI2SD指令)
因为你的汇编器不支持VCVTUSI2SD指令,我们可以基于CVTSI2SD(有符号整数转double)指令,结合无符号64位整数的特性来实现转换逻辑。核心思路是处理无符号数大于等于2^63的情况——此时它作为有符号数会被解析为负数,需要通过加法修正得到正确值。
实现代码(依赖数据段)
; 输入: rax = 待转换的无符号64位整数x ; 输出: xmm0 = 转换后的double值y unsigned_ull_to_double: ; 检查x的最高位是否为1(即x >= 2^63) test rax, rax js handle_large_val ; 最高位为1,进入特殊处理分支 ; x < 2^63时,无符号和有符号数值一致,直接转换 cvtsi2sd xmm0, rax ret handle_large_val: ; 先把x当作有符号整数转成double(此时结果为x - 2^64) cvtsi2sd xmm0, rax ; 加上2^64的double常量,修正为正确的无符号值 movsd xmm1, [rel two_to_64] addsd xmm0, xmm1 ret ; 数据段定义:2^64的double表示(十六进制0x43F0000000000000) two_to_64: dq 0x43F0000000000000
无数据段版本(位置无关代码友好)
如果不想依赖数据段,可以直接通过寄存器构造2^64的double值:
; 输入: rax = 待转换的无符号64位整数x ; 输出: xmm0 = 转换后的double值y unsigned_ull_to_double: test rax, rax js handle_large_val cvtsi2sd xmm0, rax ret handle_large_val: cvtsi2sd xmm0, rax ; 构造2^64的double值并加载到xmm1 mov rbx, 0x43F0000000000000 movq xmm1, rbx addsd xmm0, xmm1 ret
逻辑说明
- 当
x < 2^63时,无符号数和有符号数的二进制表示对应的数值完全相同,直接用CVTSI2SD转换即可得到正确结果。 - 当
x >= 2^63时,把x当作有符号整数会被解析为x - 2^64(负数),转成double后加上2^64就能还原出原始的无符号值。 - 264的double常量计算:double的指数偏移为1023,264的指数是64,所以指数部分为
1023 + 64 = 1087(十六进制0x43F),尾数部分全0,最终十六进制表示为0x43F0000000000000。
内容的提问来源于stack exchange,提问作者prz
相关产品推荐
相关产品推荐

