Demostreerimaks mäluosa stack toimimist kasutame C koodi:

23:04:40 margusja@IRack> gdb func
GNU gdb 6.3.50-20050815 (Apple version gdb-1705) (Fri Jul 1 10:50:06 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done

(gdb) list sum
1 #include
2 #include
3
4 int sum(int a, int b) {
5 int c;
6
7 c = a + b;
8 return c;
9 }
10
(gdb) list main
6
7 c = a + b;
8 return c;
9 }
10
11 void main() {
12 int a;
13 int b;
14 int c;
15
(gdb)
16 // get a and b from user
17 printf("Sisesta a:");
18 scanf("%d", &a);
19 printf("Sisesta b:");
20 scanf("%d", &b);
21
22 // do the job
23 //c = a + b;
24 c = sum(a, b);
25
(gdb)
26 // print the answer to the user
27 printf("%d + %d = %d\n", a, b, c);
28
29 }

Paneme paika vajalikud breakpointid:

(gdb)
Line number 30 out of range; func.c has 29 lines.
(gdb) b 15
Breakpoint 1 at 0x100000e34: file func.c, line 15.
(gdb) b 21
Breakpoint 2 at 0x100000e80: file func.c, line 21.
(gdb) b 6
Breakpoint 3 at 0x100000dfa: file func.c, line 6.
(gdb) b 25
Breakpoint 4 at 0x100000e94: file func.c, line 25.

Lisaks reaalsetele numbritele paistavad siin kenasti mäluaadressid, kuhu meie kood on paigutatud. Saamaks täieliku ülevaadet tõlgime koodi (tegelikult on meie kood tõlgitud) algkujule (disassemble):

(gdb) disassemble sum
Dump of assembler code for function sum:
0x0000000100000df0 : push %rbp
0x0000000100000df1 : mov %rsp,%rbp
0x0000000100000df4 : mov %edi,-0x4(%rbp)
0x0000000100000df7 : mov %esi,-0x8(%rbp)
0x0000000100000dfa : mov -0x4(%rbp),%eax
0x0000000100000dfd : mov -0x8(%rbp),%ecx
0x0000000100000e00 : add %ecx,%eax
0x0000000100000e02 : mov %eax,-0x14(%rbp)
0x0000000100000e05 : mov -0x14(%rbp),%eax
0x0000000100000e08 : mov %eax,-0x10(%rbp)
0x0000000100000e0b : mov -0x10(%rbp),%eax
0x0000000100000e0e : mov %eax,-0xc(%rbp)
0x0000000100000e11 : mov -0xc(%rbp),%eax
0x0000000100000e14 : pop %rbp
0x0000000100000e15 : retq
End of assembler dump.
(gdb) disassemble main
Dump of assembler code for function main:
0x0000000100000e20 : push %rbp
0x0000000100000e21 : mov %rsp,%rbp
0x0000000100000e24 : sub $0x10,%rsp
0x0000000100000e28 : xor %al,%al
0x0000000100000e2a : lea 0xdb(%rip),%rcx # 0x100000f0c
0x0000000100000e31 : mov %rcx,%rdi
0x0000000100000e34 : callq 0x100000ed0
0x0000000100000e39 : lea -0x4(%rbp),%rcx
0x0000000100000e3d : xor %dl,%dl
0x0000000100000e3f : lea 0xd1(%rip),%rsi # 0x100000f17
0x0000000100000e46 : mov %rsi,%rdi
0x0000000100000e49 : mov %rcx,%rsi
0x0000000100000e4c : mov %dl,%al
0x0000000100000e4e : callq 0x100000ed6
0x0000000100000e53 : xor %cl,%cl
0x0000000100000e55 : lea 0xbe(%rip),%rdx # 0x100000f1a
0x0000000100000e5c : mov %rdx,%rdi
0x0000000100000e5f : mov %cl,%al
0x0000000100000e61 : callq 0x100000ed0
0x0000000100000e66 : lea -0x8(%rbp),%rcx
0x0000000100000e6a : xor %dl,%dl
0x0000000100000e6c : lea 0xa4(%rip),%rsi # 0x100000f17
0x0000000100000e73 : mov %rsi,%rdi
0x0000000100000e76 : mov %rcx,%rsi
0x0000000100000e79 : mov %dl,%al
0x0000000100000e7b : callq 0x100000ed6
0x0000000100000e80 : mov -0x8(%rbp),%eax
0x0000000100000e83 : mov -0x4(%rbp),%ecx
0x0000000100000e86 : mov %ecx,%edi
0x0000000100000e88 : mov %eax,%esi
0x0000000100000e8a : callq 0x100000df0
0x0000000100000e8f : mov %eax,%edi
0x0000000100000e91 : mov %edi,-0xc(%rbp)
0x0000000100000e94 : mov -0x8(%rbp),%edi
0x0000000100000e97 : mov -0x4(%rbp),%r8d
0x0000000100000e9b : mov -0xc(%rbp),%r9d
0x0000000100000e9f : xor %r10b,%r10b
0x0000000100000ea2 : lea 0x7c(%rip),%r11 # 0x100000f25
0x0000000100000ea9 : mov %edi,-0x10(%rbp)
0x0000000100000eac : mov %r11,%rdi
0x0000000100000eaf : mov %r8d,%esi
0x0000000100000eb2 : mov -0x10(%rbp),%r8d
0x0000000100000eb6 : mov %r8d,%edx
0x0000000100000eb9 : mov %r9d,%ecx
0x0000000100000ebc : mov %r10b,%al
0x0000000100000ebf : callq 0x100000ed0
0x0000000100000ec4 : add $0x10,%rsp
0x0000000100000ec8 : pop %rbp
0x0000000100000ec9 : retq
End of assembler dump.
(gdb)

Paneme ajama:

(gdb) r
Starting program: /Users/margusja/Documents/c/func
Reading symbols for shared libraries +........................ done

Breakpoint 1, main () at func.c:17
17 printf("Sisesta a:");
(gdb)

Uurime main funktsiooni stacki sisu:

(gdb) info stack
#0 main () at func.c:17
(gdb)

Siin pole veel midagi huvitavat, paneme edasi:

(gdb) c
Continuing.
Sisesta a:21
Sisesta b:12

Breakpoint 2, main () at func.c:24
24 c = sum(a, b);
(gdb)

Vaatame ringi:

(gdb) info locals
a = 21
b = 12
c = 0
(gdb) info stack
#0 main () at func.c:24

Meil on main funksiooni sisesed (local) muutujad a ja b, mis on väärtustatud vastavalt 21 ja 12, funktsiooni main stack on tühi:

(gdb) info frame
Stack level 0, frame at 0x7fff5fbff710:
rip = 0x100000e80 in main (func.c:24); saved rip 0x100000de4
source language c.
Arglist at 0x7fff5fbff708, args:
Locals at 0x7fff5fbff708, Previous frame's sp is 0x7fff5fbff710
Saved registers:
rbp at 0x7fff5fbff700, rip at 0x7fff5fbff708
(gdb)

Stack level 0, frame at 0x7fff5fbff710

Laseme edasi:

(gdb) c
Continuing.

Breakpoint 3, sum (a=21, b=12) at func.c:7
7 c = a + b;
(gdb)
Siit on näha, et nüüd oleme funktsiooni sum sees func.c:7

(gdb) disassemble sum
Dump of assembler code for function sum:
0x0000000100000df0 : push %rbp
0x0000000100000df1 : mov %rsp,%rbp
0x0000000100000df4 : mov %edi,-0x4(%rbp)
0x0000000100000df7 : mov %esi,-0x8(%rbp)
0x0000000100000dfa : mov -0x4(%rbp),%eax
0x0000000100000dfd : mov -0x8(%rbp),%ecx
0x0000000100000e00 : add %ecx,%eax
0x0000000100000e02 : mov %eax,-0x14(%rbp)
0x0000000100000e05 : mov -0x14(%rbp),%eax
0x0000000100000e08 : mov %eax,-0x10(%rbp)
0x0000000100000e0b : mov -0x10(%rbp),%eax
0x0000000100000e0e : mov %eax,-0xc(%rbp)
0x0000000100000e11 : mov -0xc(%rbp),%eax
0x0000000100000e14 : pop %rbp
0x0000000100000e15 : retq
End of assembler dump.
(gdb)

Nüüd on palju huvitavam:

(gdb) info stack
#0 sum (a=21, b=12) at func.c:7
#1 0x0000000100000e8f in main () at func.c:24
(gdb) info frame
Stack level 0, frame at 0x7fff5fbff6f0:
rip = 0x100000dfa in sum (func.c:7); saved rip 0x100000e8f
called by frame at 0x7fff5fbff710
source language c.
Arglist at 0x7fff5fbff6e8, args: a=21, b=12
Locals at 0x7fff5fbff6e8, Previous frame's sp is 0x7fff5fbff6f0
Saved registers:
rsi at 0x7fff5fbff6d8, rdi at 0x7fff5fbff6dc, rbp at 0x7fff5fbff6e0, rip at 0x7fff5fbff6e8
(gdb)

Suure pusimise peale, leian ka meie väärtused 21 ja 12 mälust:

(gdb) x/10c 0x7fff5fbff6f8
0x7fff5fbff6f8: 12 '\f' 0 '\0' 0 '\0' 0 '\0' 21 '\025' 0 '\0' 0 '\0' 0 '\0'

Leave a Reply