逆向学习-字节序问题之大端与小端

本文参考

1.https://www.pediy.com/kssd/

2.http://blog.csdn.net/lanmolei814/article/details/44426651

大端、小端: 
大小端是指CPU存储数据的方式,比如一个0x01020304这个整数,在WIN、Linux下在内存中的布局如下 
[04][03][02][01] 
低地址-->高地址 

在UNIX下则是 
[01][02][03][04] 
低地址-->高地址 
通俗的说,和WIN下的内存布局一致的就是小端,和UNIX下一致的就是大端。 
其实在以前还出现过中端的的机型,不过这些机型也太“孤僻”了,已经落伍没人生产没人用了。 

那么,如何判断一个机器是大端还是小端呢
在CSAPP中,有这么一段程序
#include <stdio.h>

typedef unsigned char *byte_pointer;

void show_byte(byte_pointer start,int len)
{
    int i;
    for(i=0;i<len;i++)
    printf(" %.2x",start[i]);
    printf("\n");
}

void show_int(int x)
{
    show_byte((byte_pointer) &x,sizeof(int));
}
void show_float(float x)
{
    show_byte((byte_pointer) &x,sizeof(float));
}
void show_pointer(void *x)
{
    show_byte((byte_pointer) &x,sizeof(void *));
}


void test_show_bytes(int val)
{
    int ival = val;
    float fval = (float) ival;
    int *pval = &ival;
    show_int(ival);
    show_float(fval);
    show_pointer(pval);

}

int main()
{
    test_show_bytes(12345);//对应十六进制是0x003039
    return 0;
}



在windows机器上运行结果如下

可以看到0x3039是从低地址开始存的,我们称为小端

大小端编程检测
#include <stdio.h>

void checkdxd1(){ //通过读取同一地址的整型数据和字符数据来区别大端和小端
    unsigned int data;
    char *point=&data; //获取data的低地址,结果保存在低地址中
    data=0;
    *point= 0x22;
    if(data==0x22)
    {
        printf("此处理器是小端!\n");
    }
    else  if(data==0x22000000)
    {
        printf("此处理器是大端!\n");
    }
    else
    {
        printf("暂时无法判断机器类型!\n");
    }
}

void checkdxd2(){ //通过联合体union的共享内存特性,来判断机器类型
    union var
    {
        char str;
        int data;
    };
    union var l;
    l.data=0x01020304;
    if(l.str==0x01)
    {
        printf("此处理器是大端!\n");
    }
    else if(l.str==0x04)
    {
        printf("此处理器是小端!\n");
    }
    else{
        printf("暂时无法判断机器类型!\n");
    }
}

void checkdxd3(){ //linux内核源码改写,使用联合体
    static union
    {
        char a[4];
        unsigned long ul;
    } endian = {{'L', '?', '?', 'B'}};
    #define ENDIAN ((char)endian.ul)
    printf("%c\n", ENDIAN);//L是小端,B是大端
}

void checkdxd4() //强制类型转换
{
    int i=1;    // 1的16进制表示位0x00000001
    char *p=(char *)&i;
    //小端时,0x00000001的内存结构,[01][00][00][00] 低地址-->高地址,取&i地址则是取到低地址一个字节是[01]
    //大端时,0x00000001的内存结构,[00][00][00][01] 低地址-->高地址,取&i地址则是取到低地址一个字节是[00]
    if(*p==1)
    {
        printf("此处理器是小端!\n");
    }
    else{
        printf("此处理器是大端!\n");
    }
}


int main()
{
    checkdxd1();
    checkdxd2();
    checkdxd3();
    checkdxd4();
    return 0;
}



linux下编译
gcc -o test test.c


运行
./test



至于怎么得到大端机器将在下一篇介绍





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值