马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 kangels 于 2013-3-19 10:23 编辑 9 R( F4 C& k F8 q7 P: I! N1 z7 b
5 T' `. h4 d6 O& ^! q" l$ u2 i丢失的类型信息
: y/ _6 u. Y$ @; _猜测( N3 n1 n3 C# u9 \
指针变量应该存储两方面的信息:地址,类型信息3 i& z, g& z1 w- S
4 @1 r* k% p+ L! J* a
实证7 C+ n7 ?' }/ F a: H9 }& I
用sizeof(),float *,int*,double *....都是4字节没有存储类型信息只有地址信息
+ t1 J' C# T" X& q9 E# c; I/ u$ x反汇编一段代码来看看9 Y, n9 u5 n: c9 m
实例1:# \! n7 _$ q2 }7 S
#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
3 f# _+ g+ h- e" _0 ~3 j7 u5 [/ Z* B% v, `* @. H! {6 [( J
实例2:8 ^# L) a5 w/ Q& I. W5 h- B
#include <stdio.h> short gs; short * ps; void main(int argc, char **argv) { ps = &gs; *ps = 12; }
& b( h; o, m3 X4 y) @5 W+ h; V. N4 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 2 i: ^% R) x( F
8 A" |0 b5 i7 `- R' k: @' A/ z实例3:2 \9 K1 T" A9 A8 J" N
#include <stdio.h> char gc; char * pc; void main(int argc, char **argv) { pc = &gc; *pc = 12; }
# V6 k: u. G5 F% D/ {, d' \' L3 a" h 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 % n% }5 ^( @1 ]7 ~7 y
/ X* U5 w0 S: z) c) f
可以看出指针的类型信息决定了赋值/读取时读/写多少个字节。; {6 a J; c0 B: }* N' y0 C
读/写多少字节的信息不是存放在指针变量中,而是放到了与该地址相关的赋值指令中。1 \" h( r% m F. P9 [
|