c语言----指针偏移问题
// 麻烦解释下 在打印0x20 和 0x01 时与地址的对应关系!!!!!!
int main()
{
short s = 0x2001;
char *p = (char *)&s;
printf("%p\n", p);
printf("%p\n", p+1);
printf("%p\n", p+2);
printf("%p\n", p+3);
printf("%p\n", &s);
printf("%p\n", &s+1);
//0x7fff1d2dd7ee
//0x7fff1d2dd7ef
//0x7fff1d2dd7f0
//0x7fff1d2dd7f1
//0x7fff1d2dd7ee
//0x7fff1d2dd7f0
unsigned char c1 = *((unsigned char *)&s);
printf("%p\n", ((unsigned char *)&s) ); // 0x7fff1d2dd7ee
printf("0x%02x\n", c1); // 0x01
unsigned char c2 = *((unsigned char *)&s + 1);
printf("%p\n", ((unsigned char *)&s + 1) ); // 0x7fff1d2dd7ef
printf("0x%02x\n", c2); // 0x20
return 0;
}
[解决办法]
不要企图依赖输出指针相关表达式的值【比如printf("%p\n",...)】来理解指针的本质,
而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
1: int main() {
00401000 55 push ebp
00401001 8B EC mov ebp,esp
00401003 83 EC 54 sub esp,54h
00401006 53 push ebx
00401007 56 push esi
00401008 57 push edi
2: short s = 0x2001;
00401009 66 C7 45 FC 01 20 mov word ptr [ebp-4],offset main+0Dh (0040100d)
3: char *p = (char *)&s;
0040100F 8D 45 FC lea eax,[ebp-4]
00401012 89 45 F8 mov dword ptr [ebp-8],eax
4: void *vp;
5:
6: vp=(void *)p;
00401015 8B 4D F8 mov ecx,dword ptr [ebp-8]
00401018 89 4D F4 mov dword ptr [ebp-0Ch],ecx
7: vp=(void *)(p+1);
0040101B 8B 55 F8 mov edx,dword ptr [ebp-8]
0040101E 83 C2 01 add edx,1
00401021 89 55 F4 mov dword ptr [ebp-0Ch],edx
8: vp=(void *)(p+2);
00401024 8B 45 F8 mov eax,dword ptr [ebp-8]
00401027 83 C0 02 add eax,2
0040102A 89 45 F4 mov dword ptr [ebp-0Ch],eax
9: vp=(void *)(p+3);
0040102D 8B 4D F8 mov ecx,dword ptr [ebp-8]
00401030 83 C1 03 add ecx,3
00401033 89 4D F4 mov dword ptr [ebp-0Ch],ecx
10: vp=(void *)(&s);
00401036 8D 55 FC lea edx,[ebp-4]
00401039 89 55 F4 mov dword ptr [ebp-0Ch],edx
11: vp=(void *)(&s+1);
0040103C 8D 45 FE lea eax,[ebp-2]
0040103F 89 45 F4 mov dword ptr [ebp-0Ch],eax
12:
13: unsigned char c1 = *((unsigned char *)&s);
00401042 8A 4D FC mov cl,byte ptr [ebp-4]
00401045 88 4D F0 mov byte ptr [ebp-10h],cl
14: vp=(void *)((unsigned char *)&s);
00401048 8D 55 FC lea edx,[ebp-4]
0040104B 89 55 F4 mov dword ptr [ebp-0Ch],edx
15:
16: unsigned char c2 = *((unsigned char *)&s + 1);
0040104E 8A 45 FD mov al,byte ptr [ebp-3]
00401051 88 45 EC mov byte ptr [ebp-14h],al
17: vp=(void *)((unsigned char *)&s + 1);
00401054 8D 4D FD lea ecx,[ebp-3]
00401057 89 4D F4 mov dword ptr [ebp-0Ch],ecx
18:
19: return 0;
0040105A 33 C0 xor eax,eax
20: }
0040105C 5F pop edi
0040105D 5E pop esi
0040105E 5B pop ebx
0040105F 8B E5 mov esp,ebp
00401061 5D pop ebp
00401062 C3 ret
1: int main() {
00401000 55 push ebp
00401001 8B EC mov ebp,esp
00401003 83 EC 54 sub esp,54h
00401006 53 push ebx
00401007 56 push esi
00401008 57 push edi
2: short s = 0x2001;
00401009 66 C7 45 FC 01 20 mov word ptr [ebp-4],offset main+0Dh (0040100d)
3: char *p = (char *)&s;
0040100F 8D 45 FC lea eax,[ebp-4]
00401012 89 45 F8 mov dword ptr [ebp-8],eax
4: void *vp;
5:
6: vp=(void *)p;
00401015 8B 4D F8 mov ecx,dword ptr [ebp-8]
00401018 89 4D F4 mov dword ptr [ebp-0Ch],ecx
7: vp=(void *)(p+1);
0040101B 8B 55 F8 mov edx,dword ptr [ebp-8]
0040101E 83 C2 01 add edx,1
00401021 89 55 F4 mov dword ptr [ebp-0Ch],edx
8: vp=(void *)(p+2);
00401024 8B 45 F8 mov eax,dword ptr [ebp-8]
00401027 83 C0 02 add eax,2
0040102A 89 45 F4 mov dword ptr [ebp-0Ch],eax
9: vp=(void *)(p+3);
0040102D 8B 4D F8 mov ecx,dword ptr [ebp-8]
00401030 83 C1 03 add ecx,3
00401033 89 4D F4 mov dword ptr [ebp-0Ch],ecx
10: vp=(void *)(&s);
00401036 8D 55 FC lea edx,[ebp-4]
00401039 89 55 F4 mov dword ptr [ebp-0Ch],edx
11: vp=(void *)(&s+1);
0040103C 8D 45 FE lea eax,[ebp-2]
0040103F 89 45 F4 mov dword ptr [ebp-0Ch],eax
12:
13: unsigned char c1 = *((unsigned char *)&s);
00401042 8A 4D FC mov cl,byte ptr [ebp-4]
00401045 88 4D F0 mov byte ptr [ebp-10h],cl
14: vp=(void *)((unsigned char *)&s);
00401048 8D 55 FC lea edx,[ebp-4]
0040104B 89 55 F4 mov dword ptr [ebp-0Ch],edx
15:
16: unsigned char c2 = *((unsigned char *)&s + 1);
0040104E 8A 45 FD mov al,byte ptr [ebp-3]
00401051 88 45 EC mov byte ptr [ebp-14h],al
17: vp=(void *)((unsigned char *)&s + 1);
00401054 8D 4D FD lea ecx,[ebp-3]
00401057 89 4D F4 mov dword ptr [ebp-0Ch],ecx
18:
19: return 0;
0040105A 33 C0 xor eax,eax
20: }
0040105C 5F pop edi
0040105D 5E pop esi
0040105E 5B pop ebx
0040105F 8B E5 mov esp,ebp
00401061 5D pop ebp
00401062 C3 ret