马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 kangels 于 2013-3-19 10:23 编辑 3 U* x1 S6 d! `0 s: `( i- d$ Q9 J
. x' A5 N6 t$ F2 ]! o" {3 h8 ]
丢失的类型信息
5 ^- {# ~0 D/ x" N8 ~猜测
; m1 X [/ p' m, w6 ~! C* X" c) U指针变量应该存储两方面的信息:地址,类型信息5 Q+ f2 o1 u3 ^; N! t4 o
' P/ J9 E( _ P. Y- f+ G
实证
7 I4 `$ z& {+ m- `用sizeof(),float *,int*,double *....都是4字节没有存储类型信息只有地址信息
+ P; n) ~9 k9 O2 k% e# P: [' ~反汇编一段代码来看看
5 x0 n: e: I0 @4 H4 j5 [8 S7 A实例1:% u6 f5 ^6 u3 v0 f( u0 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 ! ^: |. [- ^+ {& ] b2 _9 L
8 k+ y) p4 K0 g' N
实例2:$ p4 d0 z: g4 K. C9 \
#include <stdio.h> short gs; short * ps; void main(int argc, char **argv) { ps = &gs; *ps = 12; } 3 M8 @$ A, `' Z5 L8 f; I, y
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 B+ A# b: H5 ^% y/ F; X" ^
. C! Z9 t+ H9 Z7 k X
实例3:
0 S6 E% I' o/ y! F1 k# y#include <stdio.h> char gc; char * pc; void main(int argc, char **argv) { pc = &gc; *pc = 12; } ( ~, R8 h5 z( x9 Y- n" Z! q3 ]; T7 z
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
1 b0 R; q \9 A: u
$ ]* x0 D" D5 u) t可以看出指针的类型信息决定了赋值/读取时读/写多少个字节。- @$ y l& E1 u- Y& `
读/写多少字节的信息不是存放在指针变量中,而是放到了与该地址相关的赋值指令中。
2 G( d; I1 O b8 {) A6 @! o |