任意解引用指针的输出

2023-12-14

我将内存填充如下:

char buf[8] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};

然后将 unsigned long 指针依次放在前 5 个字节上并输出结果:

char *c_ptr;
unsigned long *u_ptr;

c_ptr = buf;
for (int i=0;i<5;i++)
{
    u_ptr = (unsigned long *)c_ptr;
    printf("%X\n",*u_ptr);
    c_ptr++;
}

当我在 x64 平台上执行此代码时,我得到了我所期望的结果:

44332211
55443322
66554433
77665544
88776655

但是当我在 ARM 平台上执行相同的代码时,我得到以下结果:

44332211
11443322
22114433
33221144
88776655

IE。它每 4 个字节绑定一次,并且在此范围内仅取消引用 4 个字节。

所以我想问,这种行为是否(当pointer_value%4 != 0)错误或特定于实现?

更新: 我知道字节序,我想知道这是正确的,我得到

11443322

代替

55443322

例如,当我有指针时0x10000001它从带有地址的字节中生成无符号长整型0x10000001, 0x10000002, 0x10000003然后0x10000000, 代替0x10000005.


在怀疑内存对齐后,我快速谷歌了一下 =)

http://awayitworks.blogspot.co.nz/2010/02/arm-memory-alignment.html

那篇文章中指出:

直到 ARMv4 架构,假设给定的地址用于获取 内容是内存对齐的...32 位数据提取应该有地址 对齐到32位等等。正如猜对的那样,问题只是 用于 32 位和 16 位数据获取。 ARM 忽略低 2 位 如果数据获取是 32 位,则忽略低 1 位 fetch 是 16 位的。所以,总的来说,如果地址没有正确对齐 那么数据获取就会出错。

注意最后一句=)

如果您需要 x86 上预期的行为,则必须显式地从字符构建整数,ie(假设是小端):

// Endian-specific
inline unsigned long ulong_at( const char *p ) {
    return ((unsigned long)p[0])
         | (((unsigned long)p[1]) << 8)
         | (((unsigned long)p[2]) << 16)
         | (((unsigned long)p[3]) << 24);
}

也许:

// Architecture-specific
inline unsigned long ulong_at( const char *p ) {
    unsigned long val;
    char *v = (char*)&val;
    v[0] = p[0];
    v[1] = p[1];
    v[2] = p[2];
    v[3] = p[3];
    return val;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

任意解引用指针的输出 的相关文章

随机推荐