计算机底层数据的处理方式(汇编后将所有数据都转化为补码二进制数据,所有类型信息都会消失)

  编程语言是怎么实现类型转换的,而计算机底层又是怎样处理各种类型数据的呢,好吧,源码说明一切。

    code.c

[cpp] view plain copy
 
  1. int test()  
  2. {  
  3.     unsigned char a=129;  
  4.     char b=130;  
  5.     char c=a;  
  6.     int h=a;  
  7.     char d=-2;  
  8.     unsigned char e=d;  
  9.     int i=d;  
  10.     int j=a+d;  
  11.     int k=-3;  
  12.     int l=257;  
  13.     char m=k;  
  14.     char n=l;  
  15.     unsigned char p=k;  
  16.     unsigned char q=l;  
  17. }  


    将之汇编为code.s汇编代码:

    code.s

[cpp] view plain copy
 
  1. subl    $32, %esp  
  2. movb    $-127, -1(%ebp)                     //立即数都转换为相应类型所占位数下的补码数据  
  3. movb    $-126, -2(%ebp)  
  4. movb    -1(%ebp), %al  
  5. movb    %al, -3(%ebp)  
  6. movzbl  -1(%ebp), %eax  
  7. movl    %eax, -8(%ebp)  
  8. movb    $-2, -9(%ebp)  
  9. movb    -9(%ebp), %al  
  10. movb    %al, -10(%ebp)  
  11. movsbl  -9(%ebp), %eax  
  12. movl    %eax, -16(%ebp)  
  13. movzbl  -1(%ebp), %edx  
  14. movsbl  -9(%ebp), %eax  
  15. addl    %edx, %eax  
  16. movl    %eax, -20(%ebp)  
  17. movl    $-3, -24(%ebp)  
  18. movl    $257, -28(%ebp)  
  19. movl    -24(%ebp), %eax  
  20. movb    %al, -29(%ebp)  
  21. movl    -28(%ebp), %eax  
  22. movb    %al, -30(%ebp)  
  23. movl    -24(%ebp), %eax  
  24. movb    %al, -31(%ebp)  
  25. movl    -28(%ebp), %eax  
  26. movb    %al, -32(%ebp)  


    汇编后的obj文件的反汇编代码:

    

[plain] view plain copy
 
  1. code.obj:     file format pe-i386  
  2.   
  3.   
  4. Disassembly of section .text:  
  5.   
  6. 00000000 <.text>:  
  7.    0:   83 ec 20                sub    $0x20,%esp  
  8.    3:   c6 45 ff 81             movb   $0x81,-0x1(%ebp) //unsigned char a=129;     129转换为补码  
  9.    7:   c6 45 fe 82             movb   $0x82,-0x2(%ebp) //char b=130;              130转换为补码  
  10.    b:   8a 45 ff                mov    -0x1(%ebp),%al  
  11.    e:   88 45 fd                mov    %al,-0x3(%ebp)  
  12.   11:   0f b6 45 ff             movzbl -0x1(%ebp),%eax  //int h=a;                 0扩展  
  13.   15:   89 45 f8                mov    %eax,-0x8(%ebp)  
  14.   18:   c6 45 f7 fe             movb   $0xfe,-0x9(%ebp)  
  15.   1c:   8a 45 f7                mov    -0x9(%ebp),%al  
  16.   1f:   88 45 f6                mov    %al,-0xa(%ebp)  
  17.   22:   0f be 45 f7             movsbl -0x9(%ebp),%eax  //int i=d;                 符号扩展  
  18.   26:   89 45 f0                mov    %eax,-0x10(%ebp)  
  19.   29:   0f b6 55 ff             movzbl -0x1(%ebp),%edx  //int j=a+d;               将a零扩展将d符号扩展  
  20.   2d:   0f be 45 f7             movsbl -0x9(%ebp),%eax  
  21.   31:   01 d0                   add    %edx,%eax  
  22.   33:   89 45 ec                mov    %eax,-0x14(%ebp)  
  23.   36:   c7 45 e8 fd ff ff ff    movl   $0xfffffffd,-0x18(%ebp)  
  24.   3d:   c7 45 e4 01 01 00 00    movl   $0x101,-0x1c(%ebp)  
  25.   44:   8b 45 e8                mov    -0x18(%ebp),%eax             //m,m,p,q都是采用的截断操作  
  26.   47:   88 45 e3                mov    %al,-0x1d(%ebp)  
  27.   4a:   8b 45 e4                mov    -0x1c(%ebp),%eax  
  28.   4d:   88 45 e2                mov    %al,-0x1e(%ebp)  
  29.   50:   8b 45 e8                mov    -0x18(%ebp),%eax  
  30.   53:   88 45 e1                mov    %al,-0x1f(%ebp)  
  31.   56:   8b 45 e4                mov    -0x1c(%ebp),%eax  
  32.   59:   88 45 e0                mov    %al,-0x20(%ebp)  

    由代码可以看出,编译器在汇编后将所有数据都转化为补码二进制数据,所有类型信息都会消失,而底层硬件的操作对象都将是二进制补码数据。读取时将二进制数据以该类型的存储方式转换为相应的类型数据。在类型转换时采用截断、符号扩展以及零扩展的方式转换数据类型。

打印所有数据:

http://blog.csdn.net/tobacco5648/article/details/8245211

原文地址:https://www.cnblogs.com/findumars/p/6143222.html