深入理解计算机系统-之-数值存储(四)--整数在内存中的存储方式
2016-02-21 16:04
483 查看
前景回顾
前面我们了解到依据CPU的端模式的架构不同,数据的存储的字节序也不同BE big-endian 大端模式,最直观的字节序 地址低位存储值的高位,地址高位存储值的低位 ,数据填写时,不要考虑对应关系,只需要把内存地址从左到右按照由低到高的顺序写出,把值按照通常的高位到低位的顺序写出,两者对照,一个字节一个字节的填充进去。
LE little-endian 小端模式,则最符合人的思维的字节序,地址低位存储值的低位,地址高位存储值的高位 ,这点比较符合人的思维的字节序,是因为从人的第一观感来说,低位值小,就应该放在内存地址小的地方,也即内存地址低位,反之,高位值就应该放在内存地址大的地方,也即内存地址高位
任何数据在内存中都是以二进制的形式存储的。
具体参照深入理解计算机系统-之-数值存储(一)-CPU大端和小端模式详解
接着我们讨论了如何通过程序打印出变量在内存中的存储形式,具体参照深入理解计算机系统-之-数值存储(二)–C程序打印变量的每一字节或者位
然后我们了解了原码,反码,补码和移码的表示形式,具体参照深入理解计算机系统-之-数值存储(三)– 原码、反码、补码和移码详解
示例程序
那现在我们明细了。我们通过下面的程序来查看,整数在内存中的表现形式。[code]#include <stdio.h> #include <stdlib.h> int check_end() { int i = 0x12345678; char *c = (char *)&i; return (*c == 0x12); } int print_bit(void *addr, int size) { unsigned char *ptr = (unsigned char *)addr; int print_bytes = 0; if(ptr == NULL) { return -1; } for(print_bytes = 0; print_bytes < size; print_bytes++, ptr++) { #ifdef DEBUG printf("byte %d, data = %02x -=>", print_bytes, *ptr); #endif for(int print_bits = 7; print_bits >= 0; print_bits--) { printf("%d", ((*ptr >> print_bits) & 1)); } #ifdef DEBUG printf("\n"); #endif } printf("\n"); return print_bytes; } int print_byte(void *addr, int size) { unsigned char *paddr = (unsigned char *)addr; int print_bytes = 0; if(paddr == NULL) { return -1; } while(print_bytes < size) { printf("%02x", *paddr); paddr++; print_bytes++; } printf("\n"); return print_bytes; } int main(void) { if(check_end() == 1) { printf("大端模式\n"); } else { printf("小端模式\n"); } int a = 1; print_bit((void *)&a, sizeof(a)); int b = -1; print_bit((void *)&b, sizeof(b)); /* X = -00101011 = 0x0000002B [X]原= 10000000 00000000 00000000 00101011 [X]反= 11111111 11111111 11111111 11010100 [X]补= 11111111 11111111 11111111 11010101 [X]移=01010101 */ int x = 0x2B; print_bit((void *)&x, sizeof(x)); int y = -0x2B; print_bit((void *)&y, sizeof(y)); return EXIT_SUCCESS; }
程序分析
不管是原码,反码还是,补码,正数的表示方法是一致的。
但是负数来说,是有区别的。
X = -0X2B = -00101011 = 0x0000002B
[X]原 = 10000000 00000000 00000000 00101011 = 0x8000002B
[X]反 = 11111111 11111111 11111111 11010100 = 0xFFFFFFD4
[X]补 = 11111111 11111111 11111111 11010101 = 0xFFFFFFD5
[X]移 =01010101
由于我们的intel的CPU架构采用小端模式,那么用补码存储的时候,0xFFFFFFD5用小端模式存储下来,低字节到高字节的数据排列下来依次是0x D5 FF FF FF,即11010101 11111111 11111111 11111111
相关文章推荐
- 和我一起学《HTTP权威指南》——客户端识别与cookie机制
- HTTP 加密
- 李少鹏的网络日志移步到lishaopeng.com
- ANDROID_MARS学习笔记_S04_003_用HttpClent发http请求
- Java实现简单的RPC调用(基于TCP协议)
- 深入理解计算机系统-之-数值存储(三)-- 原码、反码、补码和移码详解
- C#关于HttpClient的应用(二):极光推送IM集成
- C#关于HttpClient的应用(二):融云IM集成
- C#关于HttpClient的应用(一):获取IP所在的地理位置信息
- C#关于HttpClient的统一配置(一)
- Linux命令行学习之路(十)——网络初探
- 树和递归(一)[leetcode]Balanced Binary Tree
- 如何让你的网络平台成为一个巨大磁场
- 2016大连理工大学计算机科学与技术考研经验
- opencv基本数据结构
- 数据结构(9)--链队列的定义以及相关操作的实现
- webservice 测试窗体只能用于来自本地计算机的请求
- 计算机为什么采用补码来进行运算
- 数据结构(8)--栈的应用之行编辑程序、括号匹配检验、数制转换、hanio塔问题
- 新建MAVEN工程,JSP页面报The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path