go 函数调用规则(三)

书接上回go 函数调用规则(二)
我们来解决最后一个问题
关于传参到底用哪些寄存器的问题

package main

func val(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t int) (a1 int, b1 int, c1 int, d1 int, e1 int, f1 int, g1 int, h1 int, i1 int, j1 int, k1 int, l1 int, m1 int, n1 int, o1 int, p1 int, q1 int, r1 int, s1 int, t1 int) {
	a1 = a + 2
	b1 = b * 2
	c1 = c + 3
	d1 = d * 3
	e1 = e + 4
	f1 = f * 4
	g1 = g + 1
	h1 = h + 1
	i1 = i + 1
	j1 = j + 1
	k1 = k + 1
	l1 = l + 1
	m1 = m + 1
	n1 = n + 1
	o1 = o + 1
	p1 = p + 1
	q1 = q + 1
	r1 = r + 1
	s1 = s + 1
	t1 = t + 1
	return
}

func test() {
	a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20 := val(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
	var c int = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20
	c = c + 2
}

func main() {
	test()
}

丧心病狂的传了20个参数

依旧是无关紧要的main函数

sub     rsp, 8
mov     [rsp+8+var_8], rbp
lea     rbp, [rsp+8+var_8]
call    main_test
mov     rbp, [rsp+8+var_8]
add     rsp, 8
nop
retn
sub     rsp, 280h                     #开了0x280的栈
mov     [rsp+280h+var_8], rbp         #处理一下栈底指针
lea     rbp, [rsp+280h+var_8]
mov     [rsp+280h+var_280], 0Ah       #看的出来这是后十一个参数
mov     [rsp+280h+var_278], 0Bh       #直接就在栈顶
mov     [rsp+280h+var_270], 0Ch
mov     [rsp+280h+var_268], 0Dh
mov     [rsp+280h+var_260], 0Eh
mov     [rsp+280h+var_258], 0Fh
mov     [rsp+280h+var_250], 10h
mov     [rsp+280h+var_248], 11h
mov     [rsp+280h+var_240], 12h
mov     [rsp+280h+var_238], 13h
mov     [rsp+280h+var_230], 14h
mov     eax, 1                        #所以前九个是寄存器
mov     ebx, 2                        #eax  ebx  ecx  edi  esi  r8d  r9d  r10d  r11d
mov     ecx, 3
mov     edi, 4
mov     esi, 5
mov     r8d, 6
mov     r9d, 7
mov     r10d, 8
mov     r11d, 9
nop     dword ptr [rax+00h]
call    main_val                     #去看看val函数试试
mov     rdx, [rsp+280h+var_228]      #这是在处理返回的后十一个返回值
mov     r12, [rsp+280h+var_220]      #他们都被放在栈里的十一个传参参数的后面
mov     r13, [rsp+280h+var_218]
mov     r15, [rsp+280h+var_210]
mov     [rsp+280h+var_B0], r15
mov     r15, [rsp+280h+var_208]
mov     [rsp+280h+var_B8], r15
mov     r15, [rsp+280h+var_200]
mov     [rsp+280h+var_C0], r15
mov     r15, [rsp+280h+var_1F8]
mov     [rsp+280h+var_C8], r15
mov     r15, [rsp+280h+var_1F0]
mov     [rsp+280h+var_D0], r15
mov     r15, [rsp+280h+var_1E8]
mov     [rsp+280h+var_D8], r15
mov     r15, [rsp+280h+var_1E0]
mov     [rsp+280h+var_E0], r15
mov     r15, [rsp+280h+var_1D8]
mov     [rsp+280h+var_10], rax
mov     [rsp+280h+var_18], rbx
mov     [rsp+280h+var_20], rcx
mov     [rsp+280h+var_28], rdi
mov     [rsp+280h+var_30], rsi
mov     [rsp+280h+var_38], r8
mov     [rsp+280h+var_40], r9
mov     [rsp+280h+var_48], r10
mov     [rsp+280h+var_50], r11
mov     [rsp+280h+var_58], rdx
mov     [rsp+280h+var_60], r12
mov     [rsp+280h+var_68], r13
mov     rdx, [rsp+280h+var_B0]
mov     [rsp+280h+var_70], rdx
mov     rdx, [rsp+280h+var_B8]
mov     [rsp+280h+var_78], rdx
mov     rdx, [rsp+280h+var_C0]
mov     [rsp+280h+var_80], rdx
mov     rdx, [rsp+280h+var_C8]
mov     [rsp+280h+var_88], rdx
mov     rdx, [rsp+280h+var_D0]
mov     [rsp+280h+var_90], rdx
mov     rdx, [rsp+280h+var_D8]
mov     [rsp+280h+var_98], rdx
mov     rdx, [rsp+280h+var_E0]
mov     [rsp+280h+var_A0], rdx
mov     [rsp+280h+var_A8], r15
mov     rdx, [rsp+280h+var_10]
mov     [rsp+280h+var_E8], rdx
mov     rdx, [rsp+280h+var_18]
mov     [rsp+280h+var_140], rdx
mov     rdx, [rsp+280h+var_20]
mov     [rsp+280h+var_150], rdx
mov     rdx, [rsp+280h+var_28]
mov     [rsp+280h+var_158], rdx
mov     rdx, [rsp+280h+var_30]
mov     [rsp+280h+var_160], rdx
mov     rdx, [rsp+280h+var_38]
mov     [rsp+280h+var_168], rdx
mov     rdx, [rsp+280h+var_40]
mov     [rsp+280h+var_170], rdx
mov     rdx, [rsp+280h+var_48]
mov     [rsp+280h+var_178], rdx
mov     rdx, [rsp+280h+var_50]
mov     [rsp+280h+var_180], rdx
mov     rdx, [rsp+280h+var_58]
mov     [rsp+280h+var_F0], rdx
mov     rdx, [rsp+280h+var_60]
mov     [rsp+280h+var_F8], rdx
mov     rdx, [rsp+280h+var_68]
mov     [rsp+280h+var_100], rdx
mov     rdx, [rsp+280h+var_70]
mov     [rsp+280h+var_108], rdx
mov     rdx, [rsp+280h+var_78]
mov     [rsp+280h+var_110], rdx
mov     rdx, [rsp+280h+var_80]
mov     [rsp+280h+var_118], rdx
mov     rdx, [rsp+280h+var_88]
mov     [rsp+280h+var_120], rdx
mov     rdx, [rsp+280h+var_90]
mov     [rsp+280h+var_128], rdx
mov     rdx, [rsp+280h+var_98]
mov     [rsp+280h+var_130], rdx
mov     rdx, [rsp+280h+var_A0]
mov     [rsp+280h+var_138], rdx
mov     rdx, [rsp+280h+var_A8]
mov     [rsp+280h+var_148], rdx
mov     rdx, [rsp+280h+var_E8]
add     rdx, [rsp+280h+var_140]
add     rdx, [rsp+280h+var_150]
add     rdx, [rsp+280h+var_158]
add     rdx, [rsp+280h+var_160]
add     rdx, [rsp+280h+var_168]
add     rdx, [rsp+280h+var_170]
add     rdx, [rsp+280h+var_178]
add     rdx, [rsp+280h+var_180]
add     rdx, [rsp+280h+var_F0]
add     rdx, [rsp+280h+var_F8]
add     rdx, [rsp+280h+var_100]
add     rdx, [rsp+280h+var_108]
add     rdx, [rsp+280h+var_110]
add     rdx, [rsp+280h+var_118]
add     rdx, [rsp+280h+var_120]
add     rdx, [rsp+280h+var_128]
add     rdx, [rsp+280h+var_130]
add     rdx, [rsp+280h+var_138]
add     rdx, [rsp+280h+var_148]
mov     [rsp+280h+var_188], rdx
add     rdx, 2
mov     [rsp+280h+var_188], rdx
mov     rbp, [rsp+280h+var_8]
add     rsp, 280h
retn

val

var_50= qword ptr -50h
var_48= qword ptr -48h
var_40= qword ptr -40h
var_38= qword ptr -38h
var_30= qword ptr -30h
var_28= qword ptr -28h
var_20= qword ptr -20h
var_18= qword ptr -18h
var_10= qword ptr -10h
var_8= qword ptr -8
arg_0= qword ptr  8
arg_8= qword ptr  10h
arg_10= qword ptr  18h
arg_18= qword ptr  20h
arg_20= qword ptr  28h
arg_28= qword ptr  30h
arg_30= qword ptr  38h
arg_38= qword ptr  40h
arg_40= qword ptr  48h
arg_48= qword ptr  50h
arg_50= qword ptr  58h
arg_58= qword ptr  60h
arg_60= qword ptr  68h
arg_68= qword ptr  70h
arg_70= qword ptr  78h
arg_78= qword ptr  80h
arg_80= qword ptr  88h
arg_88= qword ptr  90h
arg_90= qword ptr  98h
arg_98= qword ptr  0A0h
arg_A0= qword ptr  0A8h
arg_A8= qword ptr  0B0h
arg_B0= qword ptr  0B8h
arg_B8= qword ptr  0C0h
arg_C0= qword ptr  0C8h
arg_C8= qword ptr  0D0h
arg_D0= qword ptr  0D8h
arg_D8= qword ptr  0E0h
arg_E0= qword ptr  0E8h
arg_E8= qword ptr  0F0h
arg_F0= qword ptr  0F8h

sub     rsp, 50h
mov     [rsp+50h+var_8], rbp
lea     rbp, [rsp+50h+var_8]
mov     [rsp+50h+arg_B0], rax        #可以看到前面九个参数放在了后面十一个参数的后面
mov     [rsp+50h+arg_B8], rbx
mov     [rsp+50h+arg_C0], rcx
mov     [rsp+50h+arg_C8], rdi
mov     [rsp+50h+arg_D0], rsi
mov     [rsp+50h+arg_D8], r8
mov     [rsp+50h+arg_E0], r9
mov     [rsp+50h+arg_E8], r10
mov     [rsp+50h+arg_F0], r11
mov     [rsp+50h+var_10], 0
mov     [rsp+50h+var_18], 0
mov     [rsp+50h+var_20], 0
mov     [rsp+50h+var_28], 0
mov     [rsp+50h+var_30], 0
mov     [rsp+50h+var_38], 0
mov     [rsp+50h+var_40], 0
mov     [rsp+50h+var_48], 0
mov     [rsp+50h+var_50], 0
mov     [rsp+50h+arg_58], 0           #但是两组参数中间隔了这么一段
mov     [rsp+50h+arg_60], 0
mov     [rsp+50h+arg_68], 0
mov     [rsp+50h+arg_70], 0
mov     [rsp+50h+arg_78], 0
mov     [rsp+50h+arg_80], 0
mov     [rsp+50h+arg_88], 0
mov     [rsp+50h+arg_90], 0
mov     [rsp+50h+arg_98], 0
mov     [rsp+50h+arg_A0], 0
mov     [rsp+50h+arg_A8], 0
mov     rdx, [rsp+50h+arg_B0]
add     rdx, 2
mov     [rsp+50h+var_10], rdx
mov     rdx, [rsp+50h+arg_B8]
shl     rdx, 1
mov     [rsp+50h+var_18], rdx
mov     rdx, [rsp+50h+arg_C0]
add     rdx, 3
mov     [rsp+50h+var_20], rdx
mov     rdx, [rsp+50h+arg_C8]
lea     rdx, [rdx+rdx*2]
mov     [rsp+50h+var_28], rdx
mov     rdx, [rsp+50h+arg_D0]
add     rdx, 4
mov     [rsp+50h+var_30], rdx
mov     rdx, [rsp+50h+arg_D8]
shl     rdx, 2
mov     [rsp+50h+var_38], rdx
mov     rdx, [rsp+50h+arg_E0]
inc     rdx
mov     [rsp+50h+var_40], rdx
mov     rdx, [rsp+50h+arg_E8]
inc     rdx
mov     [rsp+50h+var_48], rdx
mov     rdx, [rsp+50h+arg_F0]
inc     rdx
mov     [rsp+50h+var_50], rdx
mov     rdx, [rsp+50h+arg_0]
inc     rdx
mov     [rsp+50h+arg_58], rdx
mov     rdx, [rsp+50h+arg_8]
inc     rdx
mov     [rsp+50h+arg_60], rdx
mov     rdx, [rsp+50h+arg_10]
inc     rdx
mov     [rsp+50h+arg_68], rdx
mov     rdx, [rsp+50h+arg_18]
inc     rdx
mov     [rsp+50h+arg_70], rdx
mov     rdx, [rsp+50h+arg_20]
inc     rdx
mov     [rsp+50h+arg_78], rdx
mov     rdx, [rsp+50h+arg_28]
inc     rdx
mov     [rsp+50h+arg_80], rdx
mov     rdx, [rsp+50h+arg_30]
inc     rdx
mov     [rsp+50h+arg_88], rdx
mov     rdx, [rsp+50h+arg_38]
inc     rdx
mov     [rsp+50h+arg_90], rdx
mov     rdx, [rsp+50h+arg_40]
inc     rdx
mov     [rsp+50h+arg_98], rdx
mov     rdx, [rsp+50h+arg_48]
inc     rdx
mov     [rsp+50h+arg_A0], rdx
mov     rdx, [rsp+50h+arg_50]
inc     rdx
mov     [rsp+50h+arg_A8], rdx
mov     rax, [rsp+50h+var_10]       #返回的时候前面九个还是寄存器返回
mov     rbx, [rsp+50h+var_18]       #那十一个返回就放在两组参数中间隔着的那么一段中欧冠返回
mov     rcx, [rsp+50h+var_20]
mov     rdi, [rsp+50h+var_28]
mov     rsi, [rsp+50h+var_30]
mov     r8, [rsp+50h+var_38]
mov     r9, [rsp+50h+var_40]
mov     r10, [rsp+50h+var_48]
mov     r11, [rsp+50h+var_50]
mov     rbp, [rsp+50h+var_8]
add     rsp, 50h
retn
main_val endp

总结一下
这次就聚焦一个问题
函数传参比较多咋办?
可以看到传参的时候首先使用九个寄存器
分别是eax ebx ecx edi esi r8d r9d r10d r11d
剩下的都放在栈顶

返回的时候也是先使用那九个寄存器 剩下的要放在传参使用的栈之后的地方。

这就是go函数调用规则。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值