我对使用gdb检测到的行为有疑问。
首先,我在64位机器上使用gcc编译了这个小程序:
#include <stdio.h>
#include <inttypes.h>
void fun (uint8_t *ar)
{
uint8_t i;
for(i = 0; i<4; i++)
{
printf("%i\n",*(&ar[0]+i));
}
}
int main (void)
{
uint8_t ar[4];
ar[0] = 0b11001100;
ar[1] = 0b10101010;
ar[2] = 0b01010110;
ar[3] = 0b00110011;
fun(ar);
return 0;
}
然后我用gdb查看ar:
的内存(gdb) p/t ar
$7 = {11001100, 10101010, 1010110, 110011}
(gdb) x ar
0x7fffffffe360: 00110011010101101010101011001100
(gdb) x 0x7fffffffe360
0x7fffffffe360: 00110011010101101010101011001100
(gdb) x 0x7fffffffe361
0x7fffffffe361: 11111111001100110101011010101010
(gdb) x 0x7fffffffe362
0x7fffffffe362: 01111111111111110011001101010110
(gdb) x 0x7fffffffe363
0x7fffffffe363: 00000000011111111111111100110011
我看到uint8_t
的数组一起收集到32位字段。对于下一个地址,这只会向右推。
&ar[0] -> {ar[3],ar[2],ar[1],ar[0]}
&ar[1] -> {xxxx,ar[3],ar[2],ar[1]}
&ar[2] -> {xxxx,xxxx,ar[3],ar[2]}
&ar[3] -> {xxxx,xxxx,xxxx,ar[3]}
这有点奇怪,我想知道:为什么会发生这种情况,我能依靠这种行为吗?这仅适用于gcc还是处理标准?
答案 0 :(得分:1)
它与字节序有关:
在x64和其他所有小端机器中,值0x12345678
的数据以78 56 34 12
形式存入内存,i。即首先是最低有效字节。
调试器知道并以这种方式向您显示。
以十六进制表示,使您的数据更易于阅读,它看起来就是这样:
你的记忆充满了
CC AA 56 33 FF 7F 00
使
3356AACC
FF3356AA
7FFF3356
007FFF33
答案 1 :(得分:1)
在gdb中,x
只打印出内存位置中的内容,无论其在C代码中的类型如何。您只是为宽度(在您的情况下为4个字节)和格式获得一些默认值(或以前使用的格式)。
例如,做x/b ar
以字节形式打印位置。并help x
了解更多信息。
如果您将其打印为除字节以外的任何内容,则处理器的endianess将确定如何解释内存。
使用p
考虑类型,如p ar