用汇编看c++中的类型转换
来源:互联网 发布:微盘,南风知我意 编辑:程序博客网 时间:2024/06/05 19:57
c++的类型转换机制,基本所有书上都有若干规则.这些规则很多,很难记.实际上类型转换机制和汇编代码表示是分不开的.本文主要从汇编代码的角度重新观察和解读c++的类型转换机制.
首先,我们看看cplusplus 对类型转换的阐述:
1. 标准转换(standard conversion)指算术类型间的转换,以及算术类型和一些指针类型的转换.
其中,较小的整型到int以及float到double的转换成为类型提升(promotion),它们不会导致精度损失.其他转换可能导致精度损失,举例如下:
负整型值转换为无符号整型,结果会是正的大整型数;
非0数转换为bool型结果为1,非NULL指针转换为bool型结果为1;
浮点数转换为整型数会导致截断(truncated),如果转换结果在整型数表示范围外,那么转换导致为定义行为(undefined behavior);
其他整型和整型,浮点型和浮点型的转换是正确的,然而结果与实现相关,也可能不可移植.
2. 数组和函数可以转换为指针;NULL可以转换为任意指针;任意指针可以转换为void指针;子类指针可以转换为父类指针.
关于类的隐式转换就不再阐述了.接下来就看看几个例子,贴出汇编代码来解读.
short a, b; cin >> a >> b; short c = a + b;汇编代码如下(忽略cin >> a >> b):
<span style="font-family:Verdana;">00232F61 movsx eax,word ptr [a] 00232F68 movsx ecx,word ptr [b] 00232F6F add eax,ecx 00232F71 mov word ptr [c],ax </span>a和b载入的都是32位寄存器,相加后截断存入c.结论就是c++的小于int的整型加法都是转换为int再计算的.
double a; char b; cin >> a >> b; double c = a + b;汇编如下:
00BF2EF5 movsx eax,byte ptr [b] 00BF2EFC mov dword ptr [ebp-30Ch],eax 00BF2F02 fild dword ptr [ebp-30Ch] 00BF2F08 fadd qword ptr [a] 00BF2F0E fstp qword ptr [c]movsx指令为带符号扩展并传送.b先转换为int,将双字存入内存,通过fild转换为double载入浮点协处理器.接下来就是浮点协处理器执行加法操作并存入c. 结论就是:小于int的整型和浮点数相加,先转换为int(如果是无符号数则使用movzx指令),再转换为浮点数(小于等于32位的整型数使用fild dword,64位整型数使用fild qword).
位操作也有类似原理.小于32位的整型转换为int(无符号转换为unsigned)再进行位运算,64位整型则是分别对低32位和高32位进行位运算.
下面是一个有趣的对比:
unsigned a = 1; int b = -1; if(a > b) cout << "aaa" << endl;int a = 1; int b = -1; if(a > b) cout << "aaa" << endl;第一行汇编如下:
00E430A2 mov dword ptr [a],1 00E430AC mov dword ptr [b],0FFFFFFFFh 00E430B6 mov eax,dword ptr [a] 00E430BC cmp eax,dword ptr [b] 00E430C2 jbe 00E430EF比较大小使用的是jbe.
第二行汇编如下:
00E430EF mov dword ptr [a],1 00E430F9 mov dword ptr [b],0FFFFFFFFh 00E43103 mov eax,dword ptr [a] 00E43109 cmp eax,dword ptr [b] 00E4310F jle 00E4313C比较大小使用的是jle.前4行汇编代码完全一致,只是通过汇编中的"有符号跳转"和"无符号跳转"的区别区分.
通过对几段汇编代码的分析,认识c++的类型转换规则更加深刻了.固然,类型转换规则的内容有与机器无关的考虑在内,但也肯定与数据的机器级表示以及指令集有密切关联.
- 用汇编看c++中的类型转换
- 从汇编角度看C语言类型转换
- C语言extern引用AT&T汇编中的变量,任意转换类型
- C#.NET 中的类型转换
- C#.NET 中的类型转换
- C#.NET 中的类型转换
- C#.NET 中的类型转换
- C#.NET 中的类型转换
- C#.NET 中的类型转换
- C#.NET 中的类型转换
- C#.NET中的类型转换
- c语言中的类型转换
- C#.NET 中的类型转换
- C#.NET 中的类型转换
- C#.NET 中的类型转换
- C#.NET 中的类型转换
- C#.NET 中的类型转换
- C#.NET 中的类型转换
- Cannot find executable for CFBundle
- Windows MFC 全局模态 实现 (二)
- MyEclipse中文乱码问题
- MySQL内核月报 2014.09
- Andriod 学习——Activity之间的跳转,以及Activity的生命周期。
- 用汇编看c++中的类型转换
- iOS Developer:真机测试
- 理解C语言-第22课 数组基础
- truncate、delete、drop三者的区别
- 简单的选择结构程序设计的总结
- 【SPOJ】913 Query on a tree II QTREE系列之2【LCA】
- 运输公司对用户计算运费.路程越远每公里运费越低.每公里每吨货物的基本运费p = 3;用户需要输入货物重量w和距离s;根据距离的不同折扣d不同(具体见)下面的表格,要求根据用户输入的w和s,计算出总运费
- 选择语句
- 关于 == 和 equals