探究float类型参数的传递方式

今天周老师在群里发了一段代码,如下:

int _tmain(int argc, _TCHAR* argv[])
{
	int i = 15;
	float m = (float)i;
	printf("%d\n",m);
	return 0;
}

并告知输出为0, 运行并且如此。查看反汇编代码如下

int _tmain(int argc, _TCHAR* argv[])
{
00F51000 55                   push        ebp  
00F51001 8B EC                mov         ebp,esp  
00F51003 83 EC 08             sub         esp,8  
	int i = 15;
00F51006 C7 45 FC 0F 00 00 00 mov         dword ptr [i],0Fh  
	float m = (float)i;
00F5100D DB 45 FC             fild        dword ptr [i]  
00F51010 D9 5D F8             fstp        dword ptr [m]  
	printf("%d\n",m);
00F51013 D9 45 F8             fld         dword ptr [m]
00F51016 83 EC 08             sub         esp,8 
00F51019 DD 1C 24             fstp        qword ptr [esp]
00F5101C 68 F4 20 F5 00       push        offset ___xi_z+34h (0F520F4h)  
00F51021 FF 15 A0 20 F5 00    call        dword ptr [__imp__printf (0F520A0h)]  
00F51027 83 C4 0C             add         esp,0Ch  
	return 0;
00F5102A 33 C0                xor         eax,eax  
}
00F5102C 8B E5                mov         esp,ebp  
00F5102E 5D                   pop         ebp  
00F5102F C3                   ret  


请注意标红的两句,明明传递的float类型,怎么需要八个字节呢? 莫非传递float类型就是这样吗?于是我又写了个测试子函数

#include "stdafx.h"

float fun(float f)
{
	return f+1;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int i = 15;
	float m = (float)i;
	float y = fun(m);
	printf("%d\n",m);
	return 0;
}


其对应的反汇编代码为

int _tmain(int argc, _TCHAR* argv[])
{
00B71020 55                   push        ebp  
00B71021 8B EC                mov         ebp,esp  
00B71023 83 EC 0C             sub         esp,0Ch  
	int i = 15;
00B71026 C7 45 F8 0F 00 00 00 mov         dword ptr [i],0Fh  
	float m = (float)i;
00B7102D DB 45 F8             fild        dword ptr [i]  
00B71030 D9 5D F4             fstp        dword ptr [m]  
	float y = fun(m);
00B71033 51                   push        ecx
00B71034 D9 45 F4             fld         dword ptr [m] 
00B71037 D9 1C 24             fstp        dword ptr [esp]
00B7103A E8 C1 FF FF FF       call        fun (0B71000h)  
00B7103F 83 C4 04             add         esp,4  
00B71042 D9 5D FC             fstp        dword ptr [y]  
	printf("%d\n",m);
00B71045 D9 45 F4             fld         dword ptr [m]  
00B71048 83 EC 08             sub         esp,8  
00B7104B DD 1C 24             fstp        qword ptr [esp]  
00B7104E 68 F4 20 B7 00       push        offset ___xi_z+34h (0B720F4h)  
00B71053 FF 15 A0 20 B7 00    call        dword ptr [__imp__printf (0B720A0h)]  
00B71059 83 C4 0C             add         esp,0Ch  
	return 0;
00B7105C 33 C0                xor         eax,eax  
}
00B7105E 8B E5                mov         esp,ebp  
00B71060 5D                   pop         ebp  
00B71061 C3                   ret  

请注意标红的汇编代码,调用fun函数时传递float类型使用了4字节,这才符合预期,但是调用printf时为何传递的8字节呢?终于baidu到这么一句话:

浮点数作为变参函数的参数时需要转换为双精度浮点值

这才揭晓了原因,原来float作为变参函数的参数需要转换为双精度浮点值(重要的话重复3遍)。

知道了这些,就不难理解本文开头的程序输出为0了, float (15) 转成双精度浮点数后,高位4字节为0,且此高4位和%d对应,故输出为0.

PS:不清楚自己分析的对不对,欢迎各路神仙留言指正。



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值