플로트 유형 매개 변수의 전달 방식을 탐구하다

3428 단어
오늘 주 선생님께서 단톡방에 다음과 같은 코드를 보내셨다.
int _tmain(int argc, _TCHAR* argv[])
{
	int i = 15;
	float m = (float)i;
	printf("%d
",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
",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 유형인데 어떻게 여덟 바이트가 필요합니까?혹시 플로트 장르를 전달하는 게 이런 건가요?그래서 나는 또 테스트 서브 함수를 썼다
#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
",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
",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는 변삼 함수의 매개 변수로서 쌍정밀도 부동점 값으로 전환해야 한다는 원인을 밝혀냈다(중요한 말은 세 번 반복한다).
이런 것을 알면 본고에서 시작한 프로그램의 출력이 0인 것을 이해하기 어렵지 않다. 플로트(15)가 쌍정밀도 부동점수로 바뀐 후 높은 4바이트가 0이고 이 높은 4비트와%d가 대응하기 때문에 출력은 0이다.
PS: 본인의 분석이 맞는지 잘 모르겠습니다. 각 분야의 신선들이 댓글로 지적하는 것을 환영합니다.


좋은 웹페이지 즐겨찾기