linux X64函数参数传递过程研究
基础知识
函数传参存在两种方式,一种是通过栈,一种是通过寄存器。对于x64体系结构,如果函数参数不大于6个时,使用寄存器传参,对于函数参数大于6个的函数,前六个参数使用寄存器传递,后面的使用栈传递。参数传递的规律是固定的,即前6个参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9,后面的依次从 “右向左” 放入栈中。
例如:
H(a, b, c, d, e, f, g, h);
a->%rdi, b->%rsi, c->%rdx, d->%rcx, e->%r8, f->%r9
h->8(%rsp)
g->(%rsp)
实验验证
源码示例
1 #include <stdio.h>
2 #include <stdlib.h>
3 int test_pass_parm(int a, int b, int c, int d, int e, int f, int g, int h)
4 {
5 printf("a:%0x, b:%0x c:%0x d:%0x e:%0x f:%0x g;%0x h:%0x\n", a,b,c,d,e,f,g,h);
6 return 0;
7 }
8 int main(int argc, char **argv)
9 {
10 int a = 1, b= 2, c=3, d = 4, e =5, f=6, g= 7, h =8;
11 test_pass_parm(a,b,c,d,e,f,g,h);
12 return 0;
13 }
使用 gcc pass_parm.c -o pass_parm -g
生成可执行程序 pass_parm
.
反汇编 pass_parm
从中我们取出来main函数以及test_pass_parm 汇编进行分析验证。
main 汇编分析
119 int main(int argc, char **argv)
120 {
121 40057b: 55 push %rbp
122 40057c: 48 89 e5 mov %rsp,%rbp
123 40057f: 48 83 ec 40 sub $0x40,%rsp //rsp栈指针下移0x40(64)个字节
124 400583: 89 7d dc mov %edi,-0x24(%rbp) // main函数的第一个参数argc放置在距离栈底0x24字节处
125 400586: 48 89 75 d0 mov %rsi,-0x30(%rbp) // main函数的第一个参数argv放置在距离栈底0x30字节处
126 int a = 1, b= 2, c=3, d = 4, e =5, f=6, g= 7, h =8;
127 40058a: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%rbp) //变量a
128 400591: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%rbp)//变量b
129 400598: c7 45 f4 03 00 00 00 movl $0x3,-0xc(%rbp)//变量c
130 40059f: c7 45 f0 04 00 00 00 movl $0x4,-0x10(%rbp)//变量d
131 4005a6: c7 45 ec 05 00 00 00 movl $0x5,-0x14(%rbp)//变量e
132 4005ad: c7 45 e8 06 00 00 00 movl $0x6,-0x18(%rbp)//变量f
133 4005b4: c7 45 e4 07 00 00 00 movl $0x7,-0x1c(%rbp) //变量g
134 4005bb: c7 45 e0 08 00 00 00 movl $0x8,-0x20(%rbp) //变量h
135 // 以上汇编将main函数的局部a, b, c, d, e, f, g, h变量从左到右依次入栈
136 test_pass_parm(a,b,c,d,e,f,g,h);
137 4005c2: 44 8b 4d e8 mov -0x18(%rbp),%r9d //传送-0x18(%rbp)(变量f) 位置的值到r9寄存器中
138 4005c6: 44 8b 45 ec mov -0x14(%rbp),%r8d //传送-0x14(%rbp)(变量e) 位置的值到r8寄存器中
139 4005ca: 8b 4d f0 mov -0x10(%rbp),%ecx //传送-0x10(%rbp)(变量d) 位置的值到cx寄存器中
140 4005cd: 8b 55 f4 mov -0xc(%rbp),%edx //传送-0xc(%rbp)(变量c) 位置的值到dx寄存器中
141 4005d0: 8b 75 f8 mov -0x8(%rbp),%esi //传送-0x8(%rbp)(变量b) 位置的值到si寄存器中
142 4005d3: 8b 45 fc mov -0x4(%rbp),%eax //暂存-0x4(%rbp)(变量a) 位置的值到ax寄存器中
143 4005d6: 8b 7d e0 mov -0x20(%rbp),%edi //传送-0x20(%rbp)(变量h) 位置的值到di寄存器中中转
144 4005d9: 89 7c 24 08 mov %edi,0x8(%rsp) //传送di寄存器的值到(变量h) 0x8(%rsp)位置
145 4005dd: 8b 7d e4 mov -0x1c(%rbp),%edi //传送-0x1c(%rbp)(变量g) 位置的值到di寄存器中中转
146 4005e0: 89 3c 24 mov %edi,(%rsp) //传送di寄存器的值到(变量g) (%rsp)位置
147 4005e3: 89 c7 mov %eax,%edi //最后将ax寄存器保存的a变量的值传送到di寄存器
148 // 以上汇编准备传给test_pass_parm函数的参数,然后调用test_pass_parm
149 4005e5: e8 33 ff ff ff callq 40051d <test_pass_parm>
150 return 0;
151 4005ea: b8 00 00 00 00 mov $0x0,%eax
152 }
153 4005ef: c9 leaveq
154 4005f0: c3 retq
155 4005f1: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
156 4005f8: 00 00 00
157 4005fb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
test_pass_parm 汇编分析
82 int test_pass_parm(int a, int b, int c, int d, int e, int f, int g, int h)
83 {
84 40051d: 55 push %rbp
85 40051e: 48 89 e5 mov %rsp,%rbp
86 400521: 48 83 ec 30 sub $0x30,%rsp
87 400525: 89 7d fc mov %edi,-0x4(%rbp) //a
88 400528: 89 75 f8 mov %esi,-0x8(%rbp) //b
89 40052b: 89 55 f4 mov %edx,-0xc(%rbp) //c
90 40052e: 89 4d f0 mov %ecx,-0x10(%rbp) //d
91 400531: 44 89 45 ec mov %r8d,-0x14(%rbp) //e
92 400535: 44 89 4d e8 mov %r9d,-0x18(%rbp) /f
93 //从寄存器恢复实参到当前函数的栈中
94 printf("a:%0x, b:%0x c:%0x d:%0x e:%0x f:%0x g;%0x h:%0x\n", a,b,c,d,e,f,g,h);
95 400539: 44 8b 45 ec mov -0x14(%rbp),%r8d
96 40053d: 8b 7d f0 mov -0x10(%rbp),%edi
97 400540: 8b 4d f4 mov -0xc(%rbp),%ecx
98 400543: 8b 55 f8 mov -0x8(%rbp),%edx
99 400546: 8b 45 fc mov -0x4(%rbp),%eax
100 400549: 8b 75 18 mov 0x18(%rbp),%esi //0x18(%rbp)的地址是上一个函数的栈顶位置 + 8,从这拿出h
101 40054c: 89 74 24 10 mov %esi,0x10(%rsp)
102 400550: 8b 75 10 mov 0x10(%rbp),%esi //0x10(%rbp)的地址是上一个函数的栈顶位置,从这拿出g
103 400553: 89 74 24 08 mov %esi,0x8(%rsp)
104 400557: 8b 75 e8 mov -0x18(%rbp),%esi
105 40055a: 89 34 24 mov %esi,(%rsp)
106 40055d: 45 89 c1 mov %r8d,%r9d
107 400560: 41 89 f8 mov %edi,%r8d
108 400563: 89 c6 mov %eax,%esi
109 400565: bf 90 06 40 00 mov $0x400690,%edi
110 40056a: b8 00 00 00 00 mov $0x0,%eax
111 // 以上汇编准备传给printf函数的参数,然后调用printf
112 40056f: e8 8c fe ff ff callq 400400 <printf@plt>
113 return 0;
114 400574: b8 00 00 00 00 mov $0x0,%eax
115 }
116 400579: c9 leaveq
117 40057a: c3 retq
实验
使用gdb进行汇编代码调试,分别在执行汇编指令的0x4005c2、0x4005e5、0x400539、0x40056f处设置断点,查看寄存器的值以及函数栈帧中的值,验证分析的结果。
设置断点
断点1处的栈数值
断点2处的栈数值以及寄存器值
断点3处的栈数值以及寄存器值
断点4处的栈数值以及寄存器值
结论
实验结果完全验证了所分析的结果,从这次实践中可以更好地了解函数参数的传递过程以及函数调用所引起的堆栈变化,完整的调试过程见附录。
附录 完整汇编与调试过程
完整汇编代码
[root@localhost test]# objdump -j .text -S pass_parm > a.txt
[root@localhost test]# nl a.txt
1 pass_parm: 文件格式 elf64-x86-64
2 Disassembly of section .text:
3 0000000000400430 <_start>:
4 400430: 31 ed xor %ebp,%ebp
5 400432: 49 89 d1 mov %rdx,%r9
6 400435: 5e pop %rsi
7 400436: 48 89 e2 mov %rsp,%rdx
8 400439: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
9 40043d: 50 push %rax
10 40043e: 54 push %rsp
11 40043f: 49 c7 c0 70 06 40 00 mov $0x400670,%r8
12 400446: 48 c7 c1 00 06 40 00 mov $0x400600,%rcx
13 40044d: 48 c7 c7 7b 05 40 00 mov $0x40057b,%rdi
14 400454: e8 b7 ff ff ff callq 400410 <__libc_start_main@plt>
15 400459: f4 hlt
16 40045a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
17 0000000000400460 <deregister_tm_clones>:
18 400460: b8 37 10 60 00 mov $0x601037,%eax
19 400465: 55 push %rbp
20 400466: 48 2d 30 10 60 00 sub $0x601030,%rax
21 40046c: 48 83 f8 0e cmp $0xe,%rax
22 400470: 48 89 e5 mov %rsp,%rbp
23 400473: 77 02 ja 400477 <deregister_tm_clones+0x17>
24 400475: 5d pop %rbp
25 400476: c3 retq
26 400477: b8 00 00 00 00 mov $0x0,%eax
27 40047c: 48 85 c0 test %rax,%rax
28 40047f: 74 f4 je 400475 <deregister_tm_clones+0x15>
29 400481: 5d pop %rbp
30 400482: bf 30 10 60 00 mov $0x601030,%edi
31 400487: ff e0 jmpq *%rax
32 400489: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
33 0000000000400490 <register_tm_clones>:
34 400490: b8 30 10 60 00 mov $0x601030,%eax
35 400495: 55 push %rbp
36 400496: 48 2d 30 10 60 00 sub $0x601030,%rax
37 40049c: 48 c1 f8 03 sar $0x3,%rax
38 4004a0: 48 89 e5 mov %rsp,%rbp
39 4004a3: 48 89 c2 mov %rax,%rdx
40 4004a6: 48 c1 ea 3f shr $0x3f,%rdx
41 4004aa: 48 01 d0 add %rdx,%rax
42 4004ad: 48 d1 f8 sar %rax
43 4004b0: 75 02 jne 4004b4 <register_tm_clones+0x24>
44 4004b2: 5d pop %rbp
45 4004b3: c3 retq
46 4004b4: ba 00 00 00 00 mov $0x0,%edx
47 4004b9: 48 85 d2 test %rdx,%rdx
48 4004bc: 74 f4 je 4004b2 <register_tm_clones+0x22>
49 4004be: 5d pop %rbp
50 4004bf: 48 89 c6 mov %rax,%rsi
51 4004c2: bf 30 10 60 00 mov $0x601030,%edi
52 4004c7: ff e2 jmpq *%rdx
53 4004c9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
54 00000000004004d0 <__do_global_dtors_aux>:
55 4004d0: 80 3d 55 0b 20 00 00 cmpb $0x0,0x200b55(%rip) # 60102c <_edata>
56 4004d7: 75 11 jne 4004ea <__do_global_dtors_aux+0x1a>
57 4004d9: 55 push %rbp
58 4004da: 48 89 e5 mov %rsp,%rbp
59 4004dd: e8 7e ff ff ff callq 400460 <deregister_tm_clones>
60 4004e2: 5d pop %rbp
61 4004e3: c6 05 42 0b 20 00 01 movb $0x1,0x200b42(%rip) # 60102c <_edata>
62 4004ea: f3 c3 repz retq
63 4004ec: 0f 1f 40 00 nopl 0x0(%rax)
64 00000000004004f0 <frame_dummy>:
65 4004f0: 48 83 3d 28 09 20 00 cmpq $0x0,0x200928(%rip) # 600e20 <__JCR_END__>
66 4004f7: 00
67 4004f8: 74 1e je 400518 <frame_dummy+0x28>
68 4004fa: b8 00 00 00 00 mov $0x0,%eax
69 4004ff: 48 85 c0 test %rax,%rax
70 400502: 74 14 je 400518 <frame_dummy+0x28>
71 400504: 55 push %rbp
72 400505: bf 20 0e 60 00 mov $0x600e20,%edi
73 40050a: 48 89 e5 mov %rsp,%rbp
74 40050d: ff d0 callq *%rax
75 40050f: 5d pop %rbp
76 400510: e9 7b ff ff ff jmpq 400490 <register_tm_clones>
77 400515: 0f 1f 00 nopl (%rax)
78 400518: e9 73 ff ff ff jmpq 400490 <register_tm_clones>
79 000000000040051d <test_pass_parm>:
80 #include <stdio.h>
81 #include <stdlib.h>
82 int test_pass_parm(int a, int b, int c, int d, int e, int f, int g, int h)
83 {
84 40051d: 55 push %rbp
85 40051e: 48 89 e5 mov %rsp,%rbp
86 400521: 48 83 ec 30 sub $0x30,%rsp
87 400525: 89 7d fc mov %edi,-0x4(%rbp)
88 400528: 89 75 f8 mov %esi,-0x8(%rbp)
89 40052b: 89 55 f4 mov %edx,-0xc(%rbp)
90 40052e: 89 4d f0 mov %ecx,-0x10(%rbp)
91 400531: 44 89 45 ec mov %r8d,-0x14(%rbp)
92 400535: 44 89 4d e8 mov %r9d,-0x18(%rbp)
93 printf("a:%0x, b:%0x c:%0x d:%0x e:%0x f:%0x g;%0x h:%0x\n", a,b,c,d,e,f,g,h);
94 400539: 44 8b 45 ec mov -0x14(%rbp),%r8d
95 40053d: 8b 7d f0 mov -0x10(%rbp),%edi
96 400540: 8b 4d f4 mov -0xc(%rbp),%ecx
97 400543: 8b 55 f8 mov -0x8(%rbp),%edx
98 400546: 8b 45 fc mov -0x4(%rbp),%eax
99 400549: 8b 75 18 mov 0x18(%rbp),%esi
100 40054c: 89 74 24 10 mov %esi,0x10(%rsp)
101 400550: 8b 75 10 mov 0x10(%rbp),%esi
102 400553: 89 74 24 08 mov %esi,0x8(%rsp)
103 400557: 8b 75 e8 mov -0x18(%rbp),%esi
104 40055a: 89 34 24 mov %esi,(%rsp)
105 40055d: 45 89 c1 mov %r8d,%r9d
106 400560: 41 89 f8 mov %edi,%r8d
107 400563: 89 c6 mov %eax,%esi
108 400565: bf 90 06 40 00 mov $0x400690,%edi
109 40056a: b8 00 00 00 00 mov $0x0,%eax
110 40056f: e8 8c fe ff ff callq 400400 printf@plt
111 return 0;
112 400574: b8 00 00 00 00 mov $0x0,%eax
113 }
114 400579: c9 leaveq
115 40057a: c3 retq
116 000000000040057b :
117 int main(int argc, char **argv)
118 {
119 40057b: 55 push %rbp
120 40057c: 48 89 e5 mov %rsp,%rbp
121 40057f: 48 83 ec 40 sub $0x40,%rsp
122 400583: 89 7d dc mov %edi,-0x24(%rbp)
123 400586: 48 89 75 d0 mov %rsi,-0x30(%rbp)
124 int a = 1, b= 2, c=3, d = 4, e =5, f=6, g= 7, h =8;
125 40058a: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%rbp)
126 400591: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%rbp)
127 400598: c7 45 f4 03 00 00 00 movl $0x3,-0xc(%rbp)
128 40059f: c7 45 f0 04 00 00 00 movl $0x4,-0x10(%rbp)
129 4005a6: c7 45 ec 05 00 00 00 movl $0x5,-0x14(%rbp)
130 4005ad: c7 45 e8 06 00 00 00 movl $0x6,-0x18(%rbp)
131 4005b4: c7 45 e4 07 00 00 00 movl $0x7,-0x1c(%rbp)
132 4005bb: c7 45 e0 08 00 00 00 movl $0x8,-0x20(%rbp)
133 test_pass_parm(a,b,c,d,e,f,g,h);
134 4005c2: 44 8b 4d e8 mov -0x18(%rbp),%r9d
135 4005c6: 44 8b 45 ec mov -0x14(%rbp),%r8d
136 4005ca: 8b 4d f0 mov -0x10(%rbp),%ecx
137 4005cd: 8b 55 f4 mov -0xc(%rbp),%edx
138 4005d0: 8b 75 f8 mov -0x8(%rbp),%esi
139 4005d3: 8b 45 fc mov -0x4(%rbp),%eax
140 4005d6: 8b 7d e0 mov -0x20(%rbp),%edi
141 4005d9: 89 7c 24 08 mov %edi,0x8(%rsp)
142 4005dd: 8b 7d e4 mov -0x1c(%rbp),%edi
143 4005e0: 89 3c 24 mov %edi,(%rsp)
144 4005e3: 89 c7 mov %eax,%edi
145 4005e5: e8 33 ff ff ff callq 40051d <test_pass_parm>
146 return 0;
147 4005ea: b8 00 00 00 00 mov $0x0,%eax
148 }
149 4005ef: c9 leaveq
150 4005f0: c3 retq
151 4005f1: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
152 4005f8: 00 00 00
153 4005fb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
154 0000000000400600 <__libc_csu_init>:
155 400600: 41 57 push %r15
156 400602: 41 89 ff mov %edi,%r15d
157 400605: 41 56 push %r14
158 400607: 49 89 f6 mov %rsi,%r14
159 40060a: 41 55 push %r13
160 40060c: 49 89 d5 mov %rdx,%r13
161 40060f: 41 54 push %r12
162 400611: 4c 8d 25 f8 07 20 00 lea 0x2007f8(%rip),%r12 # 600e10 <__frame_dummy_init_array_entry>
163 400618: 55 push %rbp
164 400619: 48 8d 2d f8 07 20 00 lea 0x2007f8(%rip),%rbp # 600e18 <__init_array_end>
165 400620: 53 push %rbx
166 400621: 4c 29 e5 sub %r12,%rbp
167 400624: 31 db xor %ebx,%ebx
168 400626: 48 c1 fd 03 sar $0x3,%rbp
169 40062a: 48 83 ec 08 sub $0x8,%rsp
170 40062e: e8 95 fd ff ff callq 4003c8 <_init>
171 400633: 48 85 ed test %rbp,%rbp
172 400636: 74 1e je 400656 <__libc_csu_init+0x56>
173 400638: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
174 40063f: 00
175 400640: 4c 89 ea mov %r13,%rdx
176 400643: 4c 89 f6 mov %r14,%rsi
177 400646: 44 89 ff mov %r15d,%edi
178 400649: 41 ff 14 dc callq *(%r12,%rbx,8)
179 40064d: 48 83 c3 01 add $0x1,%rbx
180 400651: 48 39 eb cmp %rbp,%rbx
181 400654: 75 ea jne 400640 <__libc_csu_init+0x40>
182 400656: 48 83 c4 08 add $0x8,%rsp
183 40065a: 5b pop %rbx
184 40065b: 5d pop %rbp
185 40065c: 41 5c pop %r12
186 40065e: 41 5d pop %r13
187 400660: 41 5e pop %r14
188 400662: 41 5f pop %r15
189 400664: c3 retq
190 400665: 90 nop
191 400666: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
192 40066d: 00 00 00
193 0000000000400670 <__libc_csu_fini>:
194 400670: f3 c3 repz retq
完整调试过程
[root@kfzhao test]# gdb pass_parm
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-110.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/...
Reading symbols from /root/test/pass_parm...done.
(gdb) b *0x4005c2
Breakpoint 1 at 0x4005c2: file pass_parm.c, line 13.
(gdb) b *0x4005e5
Breakpoint 2 at 0x4005e5: file pass_parm.c, line 13.
(gdb) b *0x400539
Breakpoint 3 at 0x400539: file pass_parm.c, line 6.
(gdb) b *0x40056f
Breakpoint 4 at 0x40056f: file pass_parm.c, line 6.
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005c2 in main at pass_parm.c:13
2 breakpoint keep y 0x00000000004005e5 in main at pass_parm.c:13
3 breakpoint keep y 0x0000000000400539 in test_pass_parm at pass_parm.c:6
4 breakpoint keep y 0x000000000040056f in test_pass_parm at pass_parm.c:6
(gdb) r
Starting program: /root/test/pass_parm
Breakpoint 1, main (argc=1, argv=0x7fffffffe528) at pass_parm.c:13
13 test_pass_parm(a,b,c,d,e,f,g,h);
(gdb) layout regs
(gdb) info registers
rax 0x40057b 4195707
rbx 0x0 0
rcx 0x400600 4195840
rdx 0x7fffffffe538 140737488348472
rsi 0x7fffffffe528 140737488348456
rdi 0x1 1
rbp 0x7fffffffe440 0x7fffffffe440
rsp 0x7fffffffe400 0x7fffffffe400
r8 0x7ffff7dd5e80 140737351868032
r9 0x0 0
r10 0x7fffffffdf20 140737488346912
r11 0x7ffff7a30350 140737348043600
r12 0x400430 4195376
r13 0x7fffffffe520 140737488348448
r14 0x0 0
r15 0x0 0
rip 0x4005c2 0x4005c2 <main+71>
eflags 0x206 [ PF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) x/8dw $rbp - 0x20
0x7fffffffe420: 8 7 6 5
0x7fffffffe430: 4 3 2 1
(gdb) c
Continuing.
Breakpoint 2, 0x00000000004005e5 in main (argc=1, argv=0x7fffffffe528) at pass_parm.c:13
13 test_pass_parm(a,b,c,d,e,f,g,h);
(gdb) info registers
rax 0x1 1
rbx 0x0 0
rcx 0x4 4
rdx 0x3 3
rsi 0x2 2
rdi 0x1 1
rbp 0x7fffffffe440 0x7fffffffe440
rsp 0x7fffffffe400 0x7fffffffe400
r8 0x5 5
r9 0x6 6
r10 0x7fffffffdf20 140737488346912
r11 0x7ffff7a30350 140737348043600
r12 0x400430 4195376
r13 0x7fffffffe520 140737488348448
r14 0x0 0
r15 0x0 0
rip 0x4005e5 0x4005e5 <main+106>
eflags 0x206 [ PF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) x/8dw $rbp - 0x20
0x7fffffffe420: 8 7 6 5
0x7fffffffe430: 4 3 2 1
(gdb) c
Continuing.
Breakpoint 3, test_pass_parm (a=1, b=2, c=3, d=4, e=5, f=6, g=7, h=8) at pass_parm.c:6
6 printf("a:%0x, b:%0x c:%0x d:%0x e:%0x f:%0x g;%0x h:%0x\n", a,b,c,d,e,f,g,h);
(gdb) info registers
rax 0x1 1
rbx 0x0 0
rcx 0x4 4
rdx 0x3 3
rsi 0x2 2
rdi 0x1 1
rbp 0x7fffffffe3f0 0x7fffffffe3f0
rsp 0x7fffffffe3c0 0x7fffffffe3c0
r8 0x5 5
r9 0x6 6
r10 0x7fffffffdf20 140737488346912
r11 0x7ffff7a30350 140737348043600
r12 0x400430 4195376
r13 0x7fffffffe520 140737488348448
r14 0x0 0
r15 0x0 0
rip 0x400539 0x400539 <test_pass_parm+28>
eflags 0x206 [ PF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) x/4dw $rbp + 0x10
0x7fffffffe400: 7 0 8 0
(gdb) c
Continuing.
Breakpoint 4, 0x000000000040056f in test_pass_parm (a=1, b=2, c=3, d=4, e=5, f=6, g=7, h=8) at pass_parm.c:6
6 printf("a:%0x, b:%0x c:%0x d:%0x e:%0x f:%0x g;%0x h:%0x\n", a,b,c,d,e,f,g,h);
(gdb) info registers
rax 0x0 0
rbx 0x0 0
rcx 0x3 3
rdx 0x2 2
rsi 0x1 1
rdi 0x400690 4195984
rbp 0x7fffffffe3f0 0x7fffffffe3f0
rsp 0x7fffffffe3c0 0x7fffffffe3c0
r8 0x4 4
r9 0x5 5
r10 0x7fffffffdf20 140737488346912
r11 0x7ffff7a30350 140737348043600
r12 0x400430 4195376
r13 0x7fffffffe520 140737488348448
r14 0x0 0
r15 0x0 0
rip 0x40056f 0x40056f <test_pass_parm+82>
eflags 0x206 [ PF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) p (char*)0x400690
$1 = 0x400690 "a:%0x, b:%0x c:%0x d:%0x e:%0x f:%0x g;%0x h:%0x\n"
(gdb) x/6dw $rsp
0x7fffffffe3c0: 6 32767 7 32767
0x7fffffffe3d0: 8 0
(gdb)
linux X64函数参数传递过程研究的更多相关文章
- C++ 子函数参数传递过程
编译环境:Visual Studio 2015 参数传递与汇编语言有很大关系.子函数传递参数主要方式有三种(这三种参数传递方式都可用用于x86汇编语言甚至其它汇编语言): 寄存器方式传递参数 存储器方 ...
- Linux下main函数启动过程【程序员自我修养笔记】【自用】
1. 入口函数和程序初始化 1.1 程序从main开始吗? 当程序执行到main函数的第一行时,很多事情都已经完成了: [证1]如下是一段C语言代码: 代码中可以看到,在程序刚刚执行到main的时候, ...
- Linux内核分析之跟踪分析Linux内核的启动过程
一.实验过程 使用实验楼虚拟机打开shell cd LinuxKernel/ qemu -kernel linux-/arch/x86/boot/bzImage -initrd rootfs.img ...
- 探索 Linux 系统的启动过程
引言 之所以想到写这些东西,那是因为我确实想让大家也和我一样,把 Linux 桌面系统打造成真真正正日常使用的工具,而不是安装之后试用几把再删掉.我是真的在日常生活和工作中都使用 Linux,比如在 ...
- shell 脚本之获取命令输出字符串以及函数参数传递
在ubuntu 14.04之后,所有的U盘挂载也分用户之分,最近很多操作也和U盘有关,所以就研究了一上午shell脚本函数以及字符串操作的方法. 字符串操作: 获取他的命令输出比较简单,打个简单的比方 ...
- Linux内核启动分析过程-《Linux内核分析》week3作业
环境搭建 环境的搭建参考课件,主要就是编译内核源码和生成镜像 start_kernel 从start_kernel开始,才真正进入了Linux内核的启动过程.我们可以把start_kernel看做平时 ...
- linux PCI设备初始化过程
linux PCI设备初始化过程 start_kernel->rest_init 这个函数会启动一个核心线程0, 核心线程然后调用init -> do_basic_setup. 然后我们开 ...
- VB几种函数参数传递方法,Variant,数组,Optional,ParamArray
VB几种函数参数传递方法,Variant,数组,Optional,ParamArray 一) 过程的参数被缺省为具有 Variant 数据类型. 1)ByRef按 地址传递参数在 VB 中是缺省的 按 ...
- linux(x64)下安装Matlab 2015b破解版(含安装包)
注意:在安装前请查看安装目录是否有足够空间!完全安装大概需要12G的空间!本人在安装后系统盘满了,导致无法启动图形界面.小伙伴们不要重蹈覆辙~ Environment Linux debian8 (x ...
随机推荐
- DeepCTR-Torch
仅作学习使用 在ubuntu安装成功了,可以运行example.jump2 但是在mac没有成功,报错 ImportError: No module named torch
- PHP 函数的作用
函数是为了封装方法,方便调用. 设计一个计算的代码函数.举个栗子 <?php /** * Created by PhpStorm. * User: 炜文 * Date: 2017/2/15 * ...
- JS链接转换为二维码
这里用到一个JQ插件 qrcode.js 下载地址https://github.com/jeromeetienne/jquery-qrcode 先引入 <script src="j ...
- ELK/EFK——日志收集分析平台
ELK——日志收集分析平台 ELK简介:在开源的日志管理方案之中,最出名的莫过于ELK了,ELK由ElasticSearch.Logstash和Kiabana三个开源工具组成.1)ElasticSea ...
- 【STM32H7教程】第53章 STM32H7的LTDC应用之汉字小字库和全字库制作
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第53章 STM32H7的LTDC应用之汉字小字库 ...
- 「CF741D」Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
传送门 Luogu 解题思路 考虑把22个字符状压下来,易知合法情况就是状态中之多有一个1,这个可以暴力一点判断23次. 然后后就是 dsu on the tree 了. 细节注意事项 咕咕咕 参考代 ...
- 为什么mysql having的条件表达式可以直接使用select后的别名?
SQL语句的语法顺序: FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> DISTINCT -> UNION -&g ...
- 浏览器 canvas下载图片 网络错误
在使用html2canvas截取页面的时候发现图片死活保存不到本地,chrome一直报“网络错误”, 主要出现这个问题是canvas保存图片到本地时各个浏览器像素的限制不同, 所以将图片数据转换成Bl ...
- POJ 3669 Meteor Shower BFS求最小时间
Meteor Shower Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 31358 Accepted: 8064 De ...
- P1066 图像过滤
P1066 图像过滤 转跳点: