编程语言是怎么实现类型转换的,而计算机底层又是怎样处理各种类型数据的呢,好吧,源码说明一切。
code.c
int test() { unsigned char a=129; char b=130; char c=a; int h=a; char d=-2; unsigned char e=d; int i=d; int j=a+d; int k=-3; int l=257; char m=k; char n=l; unsigned char p=k; unsigned char q=l; }
code.s
subl $32, %esp movb $-127, -1(%ebp) //立即数都转换为相应类型所占位数下的补码数据 movb $-126, -2(%ebp) movb -1(%ebp), %al movb %al, -3(%ebp) movzbl -1(%ebp), %eax movl %eax, -8(%ebp) movb $-2, -9(%ebp) movb -9(%ebp), %al movb %al, -10(%ebp) movsbl -9(%ebp), %eax movl %eax, -16(%ebp) movzbl -1(%ebp), %edx movsbl -9(%ebp), %eax addl %edx, %eax movl %eax, -20(%ebp) movl $-3, -24(%ebp) movl $257, -28(%ebp) movl -24(%ebp), %eax movb %al, -29(%ebp) movl -28(%ebp), %eax movb %al, -30(%ebp) movl -24(%ebp), %eax movb %al, -31(%ebp) movl -28(%ebp), %eax movb %al, -32(%ebp)
code.obj: file format pe-i386 Disassembly of section .text: 00000000 <.text>: 0: 83 ec 20 sub $0x20,%esp 3: c6 45 ff 81 movb $0x81,-0x1(%ebp) //unsigned char a=129; 129转换为补码 7: c6 45 fe 82 movb $0x82,-0x2(%ebp) //char b=130; 130转换为补码 b: 8a 45 ff mov -0x1(%ebp),%al e: 88 45 fd mov %al,-0x3(%ebp) 11: 0f b6 45 ff movzbl -0x1(%ebp),%eax //int h=a; 0扩展 15: 89 45 f8 mov %eax,-0x8(%ebp) 18: c6 45 f7 fe movb $0xfe,-0x9(%ebp) 1c: 8a 45 f7 mov -0x9(%ebp),%al 1f: 88 45 f6 mov %al,-0xa(%ebp) 22: 0f be 45 f7 movsbl -0x9(%ebp),%eax //int i=d; 符号扩展 26: 89 45 f0 mov %eax,-0x10(%ebp) 29: 0f b6 55 ff movzbl -0x1(%ebp),%edx //int j=a+d; 将a零扩展将d符号扩展 2d: 0f be 45 f7 movsbl -0x9(%ebp),%eax 31: 01 d0 add %edx,%eax 33: 89 45 ec mov %eax,-0x14(%ebp) 36: c7 45 e8 fd ff ff ff movl $0xfffffffd,-0x18(%ebp) 3d: c7 45 e4 01 01 00 00 movl $0x101,-0x1c(%ebp) 44: 8b 45 e8 mov -0x18(%ebp),%eax //m,m,p,q都是采用的截断操作 47: 88 45 e3 mov %al,-0x1d(%ebp) 4a: 8b 45 e4 mov -0x1c(%ebp),%eax 4d: 88 45 e2 mov %al,-0x1e(%ebp) 50: 8b 45 e8 mov -0x18(%ebp),%eax 53: 88 45 e1 mov %al,-0x1f(%ebp) 56: 8b 45 e4 mov -0x1c(%ebp),%eax 59: 88 45 e0 mov %al,-0x20(%ebp)
由代码可以看出,编译器在汇编后将所有数据都转化为补码二进制数据,所有类型信息都会消失,而底层硬件的操作对象都将是二进制补码数据。读取时将二进制数据以该类型的存储方式转换为相应的类型数据。在类型转换时采用截断、符号扩展以及零扩展的方式转换数据类型。
打印所有数据: