马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 kangels 于 2013-3-19 10:23 编辑
3 W8 O5 V. T2 }8 q9 u
4 f0 ]: j% s& P7 x1 `* l& f6 ~5 {丢失的类型信息
; g; Y/ [: e0 c k- |猜测
9 ~$ P9 w0 w( [) h/ J+ _9 F指针变量应该存储两方面的信息:地址,类型信息
- t8 C4 U# L6 Y+ A
$ k6 R7 n% k% _ E/ P" K# N; j$ }实证
1 h% \- o+ o3 Q. |1 i }用sizeof(),float *,int*,double *....都是4字节没有存储类型信息只有地址信息- h/ P$ U$ G( l
反汇编一段代码来看看
) s1 t. f; v( H2 H$ Y+ N1 A# L. J实例1:* l0 l7 c+ @( F5 R
#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
$ v; k$ h* v$ ^
* r- ^+ k1 k% z7 v) U4 ~实例2:, O$ Z( i' c4 M
#include <stdio.h> short gs; short * ps; void main(int argc, char **argv) { ps = &gs; *ps = 12; } 6 P( S" |8 \+ u) q$ g8 I# ~
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
+ J( r* {/ q% x/ B/ F. `7 @1 r7 L: S8 w+ y4 ^
实例3:& g7 D7 ~7 D: j1 p8 s& G( s
#include <stdio.h> char gc; char * pc; void main(int argc, char **argv) { pc = &gc; *pc = 12; }
! O1 S: z, C/ R s* w# T 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
. ?" ^ |, M6 s* s5 O5 i+ e- k5 x8 N( V
可以看出指针的类型信息决定了赋值/读取时读/写多少个字节。 H1 X) [2 h) X! O% J4 T3 U+ T
读/写多少字节的信息不是存放在指针变量中,而是放到了与该地址相关的赋值指令中。
& r0 {* s$ h: n0 ~( E |