马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 kangels 于 2013-3-19 10:23 编辑
4 s& k( P8 j/ Y* h& c
K" A; Z" H9 {% I1 @( Z6 \丢失的类型信息
' S' q6 {8 R9 J& I+ y" m0 t" Q猜测
/ ?/ A3 V2 F J指针变量应该存储两方面的信息:地址,类型信息- x; R" \: D* I$ v9 t. o$ P
6 b7 ^6 J, W! X3 h$ Y' T
实证$ d$ m* N/ P# Z% u' P& Y
用sizeof(),float *,int*,double *....都是4字节没有存储类型信息只有地址信息3 b) Y. l R9 B+ {. g
反汇编一段代码来看看
+ }/ J- Q% P: h实例1:
# P! m0 H# y& b#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
; }; ~# {4 s/ P6 U7 K
! S5 E" D2 a& P" j" D; B实例2:
7 K5 \+ O N7 C# X: }#include <stdio.h> short gs; short * ps; void main(int argc, char **argv) { ps = &gs; *ps = 12; } 9 A) B1 P- _* F7 u& U2 G8 S8 `2 ^
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
9 v% Z1 x( d* n0 j; o2 w( [5 E3 K
+ h* u/ m1 N$ e d% j实例3:
' E( v7 f( V/ P4 m4 d7 K* h8 j#include <stdio.h> char gc; char * pc; void main(int argc, char **argv) { pc = &gc; *pc = 12; }
+ q( O+ i! j. T$ L6 r, ?1 w1 u) ` 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
* h; ?) t N2 ]1 n$ K' E/ G0 h* ?2 Y* q: v2 u
可以看出指针的类型信息决定了赋值/读取时读/写多少个字节。) l( e9 O: }* h+ ]
读/写多少字节的信息不是存放在指针变量中,而是放到了与该地址相关的赋值指令中。
. `; ~# Z' k E5 M. P0 u& L |