2013-07-09 22 views
5

Kaynak kodu: parçalarına ayırın Ofset yığında nasıl gelir?

1  int func() 
2  { 
3   int a = 0x12345678; 
4   int *p = &a; 
5   return *p; 
6  } 

8  int main() 
9  { 
10   int b = 0x87654321; 
11   return b + func(); 
12  } 

: 0x12345678 ardından değişken a için 4 byte kaplar: Sorum

"0x000000000040052c <func()+4>: movl $0x12345678,-0xc(%rbp)" comes. 

Benim anlayış nasıl 0xc aşağıdaki doğrultusunda

(gdb) disass main 
Dump of assembler code for function main(): 
0x0000000000400544 <main()+0>: push %rbp 
0x0000000000400545 <main()+1>: mov %rsp,%rbp  
0x0000000000400548 <main()+4>: sub $0x10,%rsp 
0x000000000040054c <main()+8>: movl $0x87654321,-0x4(%rbp) 
0x0000000000400553 <main()+15>: callq 0x400528 <func()> 
0x0000000000400558 <main()+20>: add -0x4(%rbp),%eax 
0x000000000040055b <main()+23>: leaveq 
0x000000000040055c <main()+24>: retq 
End of assembler dump. 
(gdb) disass func 
Dump of assembler code for function func(): 
0x0000000000400528 <func()+0>: push %rbp 
0x0000000000400529 <func()+1>: mov %rsp,%rbp 
0x000000000040052c <func()+4>: movl $0x12345678,-0xc(%rbp) <=how -0xc comes? 
0x0000000000400533 <func()+11>: lea -0xc(%rbp),%rax 
0x0000000000400537 <func()+15>: mov %rax,-0x8(%rbp) 
0x000000000040053b <func()+19>: mov -0x8(%rbp),%rax 
0x000000000040053f <func()+23>: mov (%rax),%eax 
0x0000000000400541 <func()+25>: leaveq 
0x0000000000400542 <func()+26>: retq 
End of assembler dump. 

olduğunu

İşaretçi p için 4 bayt, kalan 4 bayt ne içindir?

Teşekkürler.

DÜZENLEME:

Linux 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:39 EDT 2010 x86_64 

DÜZENLEME 1 :: Bir soru daha: için aşağıdaki satırı nedir? fonk iken ("alt $ 0x10,% rsp" tarafından) () ana 16 byte ile uyumlu hale getirilmesi gerekmektedir Neden:

0x0000000000400544 <main()+0>: push %rbp 
0x0000000000400545 <main()+1>: mov %rsp,%rbp  
0x0000000000400548 <main()+4>: sub $0x10,%rsp <== ? 

DÜZENLEME 2: function main() için montajcı kodunun

Dökümü değil (0x0c hizalanmış değil, değil mi?)? işaretçi "p" için 4 bayt ardından

+0

makineniz 64 bit ve makinenizde adres 8 byte değil 4 bayt –

+0

Evet, çok teşekkür ederim olduğunu görünüyor. –

cevap

10

Linux 2.6.18-194.el5 1. SMP Sal 16 Mart 21:52:39 EDT 2010 x86_64

... .. .

64 bit = 8 bayt Sen, 64 bit mimarisine yüzden bir işaretçi kaplar:

#include <stdio.h> 

int main() { 
    int a = 0x12345678; 
    int *p = &a; 

    printf("%zu\n", sizeof(p)); 
    printf("%zu\n", sizeof(a)); 

    return 0; 
} 
$ gcc -std=c99 -Wall -pedantic -o sample sample.c 
$ ./sample 
8 
4 

Detaylı yığın analizi:

0x0000000000400528 <func()+0>: push %rbp 
0x0000000000400529 <func()+1>: mov %rsp,%rbp 
+..........+ 
| RET ADDR | (from CALL) 
+----------+ 
|RBP (high)| 
+..........| 
|RBP (low) | <== RSP, RBP 
+----------+ 
|   | <== -0x4(%rbp) -\ 
+..........+     \__ int *p 
|   | <== -0x8(%rbp) /
+----------+    -/ 
|   | <== -0xc(%rbp)  int a 
+----------+ 

için:

func() giren ilk iki komutları yerine sonra yığın şöyle

(her dikdörtgen belleğin 4 bayt olduğunu kabul) sonra yerel a değişkene bir değer depolamak gibidir: sonra

0x000000000040052c <func()+4>: movl $0x12345678,-0xc(%rbp) <=how -0xc comes? 
+..........+ 
| RET ADDR | (from CALL) 
+----------+ 
|RBP (high)| 
+..........| 
|RBP (low) | <== RSP, RBP 
+----------+ 
|   | <== -0x4(%rbp) -\ 
+..........+     \__ int *p 
|   | <== -0x8(%rbp) /
+----------+    -/ 
|0x12345678| <== -0xc(%rbp)  int a 
+----------+ 

, sen sto vardır p değişkene 64 bit işaretçi halka:

0x0000000000400533 <func()+11>: lea -0xc(%rbp),%rax ; load address of a into RAX 
0x0000000000400537 <func()+15>: mov %rax,-0x8(%rbp) ; store address into pointer (64 bit) 
+..........+ 
| RET ADDR | (from CALL) 
+----------+ 
|RBP (high)| 
+..........| 
|RBP (low) | <== RSP, RBP 
+----------+ 
| &a (high)| <== -0x4(%rbp) -\ 
+..........+     \__ int *p 
| &a (low) | <== -0x8(%rbp) /
+----------+    -/ 
|0x12345678| <== -0xc(%rbp)  int a 
+----------+ 
+0

Güzel seçim, OP soruya cevap verdi! –

+1

Evet, iyi şanslar o ark adını gönderdi :) –

+0

Ana bildirim(): 'movl $ 0x87654321, -0x4 (% rbp)' '' 4'te bayt. ..Ana() ve func() farklı nasıl olabilir –