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
|
SUBQ $136, SP // 开辟136字节的栈空间
// SUBX a, b 表示将 b-=a
MOVQ BP, 128(SP) // 将BP的值写入[128:136]
// MOVX a, b 表示将 a的值 写入 b
LEAQ 128(SP), BP // 将[128:136]的地址写入BP
// LEAX a, b 表示将 a的地址 写入 b
MOVQ $1, "".a+96(SP) // 将1写入[96:104], 即[96:104]存储a(1)
MOVQ $2, "".b+80(SP) // 将1写入[80:88], 即[80:86]存储b(2)
MOVQ $3, "".c+72(SP) // 将1写入[72:80], 即[72:80]存储c(3)
MOVQ "".b+80(SP), AX // 将[80:88]的值写入AX寄存器(b=2)
MOVQ "".a+96(SP), CX // 将[96:108]的值写入CX寄存器(a=1)
MOVQ CX, (SP) // 将CX寄存器的值写入[0:8](1,函数参数a)
MOVQ AX, 8(SP) // 将AX寄存器的值写入[8:16](2,函数参数b)
MOVQ $3, 16(SP) // 将1写如[16:24](3,函数参数c)
// 按照地址高低可以看到是c>b>a,所以说参数是从右到左入栈
// 此时的栈布局为
// ------------------------
// top
// BP 128:136
// 空闲 104:128
// a 96:104
// 空闲 88:96
// b 80:88
// c 72:80
// 空闲 24:72
// 参数c 16:24
// 参数b 8:16
// 参数a 0:8 SP=0
// ------------------------
// 可以看见参数和返回都是在main栈中的
CALL "".add(SB) // 调用add方法,这里会SP=SP-8,这个8个字节用来存储main的返回地址
// 由于add中没有局部变量,所以没有生成栈,直接操作了main栈中的参数和返回
// 初始化返回参数
MOVQ $0, "".~r3+32(SP) // 将0写入 [32:40] (main中[24:32]) 返回参数1
MOVQ $0, "".~r4+40(SP) // 将0写入 [40:48] (main中[32:40]) 返回参数2
MOVQ $0, "".~r5+48(SP) // 将0写入 [48:56] (main中[40:48]) 返回参数3
// 计算 a+b
MOVQ "".a+8(SP), AX // 将 [8:16] (main中[0:8]) 的值写入AX寄存器 (参数a)
ADDQ "".b+16(SP), AX // 将 [16:24] (main中[8:16]) (参数b) 的值与AX寄存器相加,然后再写入AX寄存器 (a+b)
MOVQ AX, "".~r3+32(SP) // 将AX寄存器的值写入 [32:40] (main中[24:32]) 返回参数1
// 计算 b+c
MOVQ "".b+16(SP), AX // 将 [16:24] (main中[8:16]) 的值写入AX寄存器 (参数b)
ADDQ "".c+24(SP), AX // 将 [24:32] (main中[16:24]) (参数c) 的值与AX寄存器相加,然后再写入AX寄存器
MOVQ AX, "".~r4+40(SP) // 将AX寄存器的值写入 [40:48] (main中[32:40]) 返回参数2
// 计算 a+c
MOVQ "".a+8(SP), AX // 将 [8:16]( main中[0:8]) 的值写入AX寄存器 (参数a)
ADDQ "".c+24(SP), AX // 将 [24:32] main中[16:24]) (参数c) 的值与AX寄存器相加,然后再写入AX寄存器
MOVQ AX, "".~r5+48(SP) // 将AX寄存器的值写入 [48:56] (main中[40:48]) 返回参数3
// 此时的栈布局为
// ------------------------
// top
// BP 128:136
// 空闲 104:128
// a 96:104
// 空闲 88:96
// b 80:88
// c 72:80
// 空闲 48:72
// 返回参数3 40:48
// 返回参数2 32:40
// 返回参数1 24:32
// 参数c 16:24
// 参数b 8:16
// 参数a 0:8
// 返回地址 -8:0 SP=-8
// ------------------------
RET // 将SP返回到main中,SP+=8
MOVQ 24(SP), AX // 将 [24:32] 的值写入AX寄存器 (返回值1)
MOVQ 32(SP), CX // 将 [32:40] 的值写入CX寄存器 (返回值2)
MOVQ 40(SP), DX // 将 [40:48] 的值写入DX寄存器 (返回值3)
MOVQ AX, ""..autotmp_7+120(SP) // 将AX的值写入 [120:128] (临时变量x)
MOVQ CX, ""..autotmp_8+112(SP) // 将CX的值写入 [112:120] (临时变量y)
MOVQ DX, ""..autotmp_9+104(SP) // 将DX的值写入 [104:112] (临时变量z)
MOVQ ""..autotmp_7+120(SP), AX // 将 [120:128] 的值写入 AX
MOVQ AX, "".x+64(SP) // 将 AX的值写入 [64:72] (变量x)
MOVQ ""..autotmp_8+112(SP), AX // 将 [112:120] 的值写入 AX
MOVQ AX, "".y+56(SP) // 将 AX的值写入 [56:64] (变量y)
MOVQ ""..autotmp_9+104(SP), AX // 将 [104:112] 的值写入 AX
MOVQ AX, "".z+48(SP) // 将 AX的值写入 [48:56] (变量z)
MOVQ "".x+64(SP), AX // 将 x的值写入AX
ADDQ "".y+56(SP), AX // 计算 AX+=y
ADDQ "".z+48(SP), AX // 计算 AX+=z
MOVQ AX, "".all+88(SP) // 将AX的值写入 [88:96]
// 此时的栈布局为
// ------------------------
// top
// BP 128:136
// 临时变量x 120:128
// 临时变量y 112:120
// 临时变量z 104:112
// a 96:104
// all 88:96
// b 80:88
// c 72:80
// x 64:72
// y 56:64
// z 48:56
// 返回参数3 40:48
// 返回参数2 32:40
// 返回参数1 24:32
// 参数c 16:24
// 参数b 8:16
// 参数a 0:8 SP=0
// ------------------------
CMPQ AX, $10 // 比较AX和10
JEQ 200 // 如果相同跳转到200行
JMP 218 // 如果不同,跳转到218行
JMP 202 // 跳转到202行
MOVQ 128(SP), BP // 恢复BP的值
ADDQ $136, SP // 回收栈空间,此处只是回收,并没有清空
RET // 返回
|