马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 kangels 于 2013-3-19 10:23 编辑 ( I# P, K: b" E
7 r9 J4 W+ R: V. r; r @
丢失的类型信息4 M" E8 w/ q( `8 D
猜测" ~1 b2 R/ H7 T
指针变量应该存储两方面的信息:地址,类型信息& I2 g$ L/ v% Y* C$ i0 u M# q
: ]* G& ~5 {+ l* [+ M2 v
实证
5 x) y. i. ~' R用sizeof(),float *,int*,double *....都是4字节没有存储类型信息只有地址信息3 R& y1 N( S: t9 o. S+ L
反汇编一段代码来看看2 }2 f- y3 C2 c/ U
实例1:
; z+ k* q2 y! d% q' S+ t#include <stdio.h> int gi; int * pi; void main(int argc, char **argv) { pi = &gi; *pi = 12; } 1: #include <stdio.h> 2: int gi; 3: int * pi; 4: void main(int argc, char **argv) 5: { 00411370 push ebp 00411371 mov ebp,esp 00411373 sub esp,0C0h 00411379 push ebx 0041137A push esi 0041137B push edi 0041137C lea edi,[ebp+FFFFFF40h] 00411382 mov ecx,30h 00411387 mov eax,0CCCCCCCCh 0041138C rep stos dword ptr es:[edi] 6: pi = &gi; 0041138E mov dword ptr ds:[00417140h],417144h 7: *pi = 12; 00411398 mov eax,dword ptr ds:[00417140h] 0041139D mov dword ptr [eax],0Ch 8: } 004113A3 xor eax,eax 004113A5 pop edi 004113A6 pop esi 004113A7 pop ebx 004113A8 mov esp,ebp 004113AA pop ebp 004113AB ret N s0 w% _5 m& r. v8 i
4 P% Y$ ], P3 X! E! a; `实例2:
/ c# u1 h: [8 T2 Z+ \/ Q#include <stdio.h> short gs; short * ps; void main(int argc, char **argv) { ps = &gs; *ps = 12; }
- x7 c0 [$ ^4 @9 e! p 1: #include <stdio.h> 2: short gs; 3: short * ps; 4: void main(int argc, char **argv) 5: { 00411370 push ebp 00411371 mov ebp,esp 00411373 sub esp,0C0h 00411379 push ebx 0041137A push esi 0041137B push edi 0041137C lea edi,[ebp+FFFFFF40h] 00411382 mov ecx,30h 00411387 mov eax,0CCCCCCCCh 0041138C rep stos dword ptr es:[edi] 6: ps = &gs; 0041138E mov dword ptr ds:[00417140h],417144h 7: *ps = 12; 00411398 mov eax,0Ch 0041139D mov ecx,dword ptr ds:[00417140h] 004113A3 mov word ptr [ecx],ax 8: } 004113A6 xor eax,eax 004113A8 pop edi 004113A9 pop esi 004113AA pop ebx 004113AB mov esp,ebp 004113AD pop ebp 004113AE ret 0 X4 D( G* e# O. x1 W [8 e* [
9 c, T9 d% @9 J0 t! `2 w: [实例3:9 s( r0 b/ H$ R- ~8 J4 b
#include <stdio.h> char gc; char * pc; void main(int argc, char **argv) { pc = &gc; *pc = 12; } 1 N7 r0 V( @" I8 t. ^/ h* g) M
1: #include <stdio.h> 2: char gc; 3: char * pc; 4: void main(int argc, char **argv) 5: { 00411370 push ebp 00411371 mov ebp,esp 00411373 sub esp,0C0h 00411379 push ebx 0041137A push esi 0041137B push edi 0041137C lea edi,[ebp+FFFFFF40h] 00411382 mov ecx,30h 00411387 mov eax,0CCCCCCCCh 0041138C rep stos dword ptr es:[edi] 6: pc = &gc; 0041138E mov dword ptr ds:[00417140h],417144h 7: *pc = 12; 00411398 mov eax,dword ptr ds:[00417140h] 0041139D mov byte ptr [eax],0Ch 8: } 004113A0 xor eax,eax 004113A2 pop edi 004113A3 pop esi 004113A4 pop ebx 004113A5 mov esp,ebp 004113A7 pop ebp 004113A8 ret
. z6 y5 @* f& a# U9 f2 W. v
& d, W% r! T$ N, {! `- h可以看出指针的类型信息决定了赋值/读取时读/写多少个字节。
: s* S9 X6 I- G) X' B7 G读/写多少字节的信息不是存放在指针变量中,而是放到了与该地址相关的赋值指令中。" d/ u/ w! r- d% P! x* c$ S
|