1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
;============================================================================
_funciton1 proc
push ebp
mov ebp, esp
;============================================================================
; p++
; 这里加了240是这样计算出来的, p本身是一个int*** (*p)[3][4][5]类型的变量,
; 按照唐老师的方法, 去掉一个*看类型那么就是int*** (p)[3][4][5]那么, 也就是
; 一个数组的大小了, (3*4*5)*4 = 240 所以p++是加240
;============================================================================
mov eax, dword ptr _p$[ebp]
add eax, 240 ; 000000f0h
mov dword ptr _p$[ebp], eax
;============================================================================
; *p++
; 这里这个问题一直是我以前所困扰的, 我以前一直认为*p++是p所指向的内容++
; 但是很明显也是加了240, 主要的问题只有一个, 就是++的运算符级别比*高,
; 所以要先和++结合, 剩下的就和我们声明的int变量 a++一样了..
;============================================================================
mov ecx, dword ptr _p$[ebp]
add ecx, 240 ; 000000f0h
mov dword ptr _p$[ebp], ecx
;============================================================================
; p[2][3][4][5][6][7][8] = 50;
; 上面声明p是int*** (*p)[3][4][5]类型, 使用的时候用的全是[], 有点郁闷.
; 那么或许我们换成这种形式可以看更清楚一些.前面这种是全*访问,
; 后面这种才是应该的正统访问方式
; (*(*(* (*(*(* (*(p+2) +3)+4)+5) +6)+7)+8)) = 50 ;全*
; *(*(* ((*(p+2)) [3][4][5] +6)+7)+8) = 50; ;正统访问方式
;820 = ( sizeof(int)*(3*4*5)*2 ) + (sizeof(int)*(4*5))*3 + (sizeof(int)*5*4)+ sizeof(int***)*5
; 所以以前认为[]和*没有理解好, 虽然这里每种方式都可以访问, 生成的汇编
; 代码也是一样的, 但是自己要注意区分, 这里的3, 4, 5都是属于数组的, 前面的
; 2是属于*p的, 其大小就是整个的数组大小.
;============================================================================
mov edx, dword ptr _p$[ebp]
mov eax, dword ptr [edx+820]
mov ecx, dword ptr [eax+24]
mov edx, dword ptr [ecx+28]
mov dword ptr [edx+32], 50 ; 00000032h
;============================================================================
; a++
; a++的话由于a其实只是一个这种类型的指针 int a* [7][8][9]
; 那么a++的话其实就是 a += (7*8*9)*4 ;2016
;============================================================================
mov eax, dword ptr _a$[ebp]
add eax, 2016 ; 000007e0h
mov dword ptr _a$[ebp], eax
;============================================================================
; ((((a[2]+3)[4])+5)[6])[5] = 10;
; 那么这句代码其实是这种形式了.
; a[2][7][11][5] = 10
; 所以计算出来应该是这样的
; a + 2*(7*8*9)*4 + 7*(8*9)*4 + 11*(9*4) + 5*4 ;6464
;============================================================================
mov ecx, dword ptr _a$[ebp]
mov dword ptr [ecx+6464], 10 ; 0000000ah
;============================================================================
; *(&a) += 1
; 这里再一次证明了数组只是一个指针名称, 传递参数里面.是没有数组的!
; 当然这里是一句废话, *&同时出现是会抵消的, 所以其实是这句
; a += 1
;============================================================================
mov edx, dword ptr _a$[ebp]
add edx, 2016 ; 000007e0h
mov dword ptr _a$[ebp], edx
xor eax, eax
pop ebp
ret 0
_funciton1 endp
;============================================================================
;这是function2生成的代码
;============================================================================
_funciton2 proc
push ebp
mov ebp, esp
;============================================================================
; 这里是代码有少量优化的效果, push ecx而不用sub esp, 4这句上面代码有体现
; a += ((7*8*9)*4) ;2016
;============================================================================
; a++;
push ecx
mov eax, dword ptr _a$[ebp]
add eax, 2016 ; 000007e0h
mov dword ptr _a$[ebp], eax
;============================================================================
;这里是以前正常的把带*参数当成数组来用的例子, 其实是这种形式
;a + 3*(7*8*9)*4 + 2*(8*9)*4 + 1*(9*4) + 4*1*4 ;6676
;============================================================================
;a[3][2][1][4] ='A';
mov ecx, dword ptr _a$[ebp]
mov dword ptr [ecx+6676], 65 ; 00000041h
;============================================================================
;p[6][5][4][3][2] [1][3][2][1] [1][2][3][4][5][6] = 2;
;其实下面这个表达式才是正统的写法.
;*(*(*(*(*(*( ((*(*(*(*(*(p+6)+5)+4)+3)+2)) [1][3][2][1] )+1)+2)+3)+4)+5)+6) = 2;
;或者换成全*方式
;*(*(*(*(*(*( (*(*(*(*(*(*(*(*(*(p+6)+5)+4)+3)+2) +1)+3)+2)+1) )+1)+2)+3)+4)+5)+6) = 2;
;主要就是要区分好数组和指针之间的关系, 虽然可以套用. 但是自己心里一定
;要明白.目前是什么..
;[1][3][2][1] = 1*(10*8*6)*4 + 3*(8*6)*4 + 2*(6*4)+1*4 ;2548
;============================================================================
mov edx, dword ptr _p$[ebp]
mov eax, dword ptr [edx+24]
mov ecx, dword ptr [eax+20]
mov edx, dword ptr [ecx+16]
mov eax, dword ptr [edx+12]
mov ecx, dword ptr [eax+8]
mov edx, dword ptr [ecx+2548]
mov eax, dword ptr [edx+4]
mov ecx, dword ptr [eax+8]
mov edx, dword ptr [ecx+12]
mov eax, dword ptr [edx+16]
mov ecx, dword ptr [eax+20]
mov dword ptr [ecx+24], 2
;============================================================================
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_funciton2 endp
|