九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Linux環(huán)境下的堆棧

http://blog.csdn.net/unix21/article/details/8498109

2013

完整的調(diào)試過程,跟蹤堆棧變化,32位下。

注意64位和此不同。

 

a.c代碼:

#include <stdio.h>   int main()  {      AFunc(5,6);    return 0;}  int BFunc(int i,int j){	int m = 1;	int n = 2;	m = i;	n = j; 	return m;}       int AFunc(int i,int j){    int m = 3;    int n = 4;         m = i;    n = j;    BFunc(m,n);    return 8;}


編譯加上調(diào)試信息

#gcc  -g  -o  a a.c

 

要調(diào)試C程序,在編譯時(shí),必須要把調(diào)試信息加到可執(zhí)行文件中。使用編譯器(cc/gcc/g++)的 -g 參數(shù)可以做到這一點(diǎn)。如:

    > cc -g hello.c -o hello
    > g++ -g hello.cpp -o hello

如果沒有-g,你將看不見程序的函數(shù)名、變量名,所代替的全是運(yùn)行時(shí)的內(nèi)存地址。

啟動(dòng)gdb

#gdb a

 

增加斷點(diǎn)

#break *main

運(yùn)行

#run

步入

#s     進(jìn)入的單步執(zhí)行

如果已經(jīng)進(jìn)入了某函數(shù),而想退出該函數(shù)返回到它的調(diào)用函數(shù)中,可使用命令finish
#finsh

#n    不進(jìn)入的單步執(zhí)行

查看數(shù)組的值
有時(shí)候,你需要查看一段連續(xù)的內(nèi)存空間的值。比如數(shù)組的一段,或是動(dòng)態(tài)分配的數(shù)據(jù)的大小。你可以使用GDB的“@”操作符,“@”的左邊是第一個(gè)內(nèi)存的地址的值,“@”的右邊則你你想查看內(nèi)存的長(zhǎng)度。例如,你的程序中有這樣的語句:
int *array = (int *) malloc (len * sizeof (int));
于是,在GDB調(diào)試過程中,你可以以如下命令顯示出這個(gè)動(dòng)態(tài)數(shù)組的取值:
#p *array@len
如果是靜態(tài)數(shù)組的話,可以直接用print數(shù)組名,就可以顯示數(shù)組中所有數(shù)據(jù)的內(nèi)容了。

 

whatis 命令可以顯示某個(gè)變量的類型
(gdb) whatis p
type = int *

 

查看匯編

#disas

#bt 查看棧幀

#f 0查看第0幀

#f 1查看第1幀

#f N查看第N幀

之后查看寄存器也會(huì)查看對(duì)應(yīng)的寄存器

#i r

之后也會(huì)查看對(duì)應(yīng)寄存器內(nèi)容

#x/40xw $esp

查看堆棧底

#x/40xw $ebp

--《深入理解計(jì)算機(jī)系統(tǒng)(原書第2版)》

開始

1.main函數(shù)中第1個(gè)s

ebp的內(nèi)容為0

 

2.main函數(shù)中第2個(gè)s,開始調(diào)用A函數(shù)

很明顯esp和ebp變化了,上一步的ebp地址被pusp到新的ebp的內(nèi)容。

 

3.進(jìn)入A函數(shù)

顯示ebp入棧;

然后esp指向新的ebp

sub $0x18,%esp即esp減少24個(gè)地址;0xbffff618-18=0xbffff600

第1幀:

第0幀:

ebp依次保存了:

“上一個(gè)ebp的地址  0xbffff638

“main函數(shù)中調(diào)用完A函數(shù)后的執(zhí)行地址 0x080483b1”;

“上級(jí)函數(shù)傳遞的參數(shù)5保存在ebp的正向地址”;

“上級(jí)函數(shù)傳遞的參數(shù)6保存在ebp的正向地址”

將進(jìn)入AFunc函數(shù)之前的EBP的值入棧保存,這時(shí)候的EBP相當(dāng)于是AFunc上級(jí)函數(shù); 的一個(gè)現(xiàn)場(chǎng)信息,所以需要保存起來,以便于AFunc返回后上級(jí)函數(shù)可以恢復(fù)EBP使其指向其調(diào)用; AFunc之前的堆棧位置(當(dāng)然,這還需要靠恢復(fù)ESP來協(xié)助達(dá)到這一目的)

 

4.A函數(shù)中int n=4前

0x8(%ebp)的-8個(gè)位置存放3;

0x4(%ebp)的-4個(gè)位置存放4。

注意:這里如果調(diào)用f 0則后面的i r和x/40xw $ebp都是查看該棧幀

 

5.A函數(shù)m=j前

函數(shù)的局部變量放置在EBP的負(fù)偏移處(Negative; Offset)也就是向低地址方向。

esp在0xbffff618,3和4分別在0xbffff610和0xbffff614。

 

6.A函數(shù)n=j之前

 

0x8(ebp)獲取ebp正向地址的值稍后mov到eax寄存器;

然后將eax寄存器中的5移到-0x8(ebp)即ebp的負(fù)地址8

0xbffff610處的3已經(jīng)被替換為5

 

7.進(jìn)入B函數(shù)之前

0xc(%ebp)從ebp高地址獲取6并存儲(chǔ)在ebp的低地址-4位置,然后放到eax寄存器

 0xbffff614處的4已經(jīng)被替換為6

 

8.進(jìn)入B函數(shù)

按之前的第7步在進(jìn)入B函數(shù)之前先把參數(shù)5和6從ebp的-4和-8地址上取出存在eax寄存器,然后存儲(chǔ)到esp的正向地址上

esp和ebp存儲(chǔ)新的內(nèi)存地址位置

參數(shù)5和6依次保存在esp的正向地址中

 

8.B函數(shù)n=2之前

第2幀:

第1幀:

第一幀的ebp保存著:

main函數(shù)的ebp地址0xbffff638;

以及main函數(shù)需要繼續(xù)執(zhí)行的地址0x080483b1

 

第0幀:

這是當(dāng)前B函數(shù)的幀以及對(duì)應(yīng)的寄存器內(nèi)容,其中1被存儲(chǔ)在ebp的-8位置,和之前的A函數(shù)中的過程一樣,沒有新的差異。

 

9.B函數(shù)的m=i之前

 

10.B函數(shù)的n=j之前

 

11.B函數(shù)return之前

 

12.B函數(shù)返回值

leave 將ebp值賦給esp,

pop先前棧內(nèi)的上級(jí)函數(shù)棧的基地址給ebp,

恢復(fù)原?;废喈?dāng)于:

movl %ebp,%esp  

popl %ebp

返回值放在eax寄存器中

 

13.回到A函數(shù)

8賦給eax寄存器

 

14.A返回值,pop出main函數(shù)的ebp

 

15.回到main函數(shù)

 

16.退出main函數(shù)

 

17.進(jìn)入__libc_start_main ()系統(tǒng)調(diào)用

18.結(jié)束

 

關(guān)于win32環(huán)境下的堆棧參考:Win32 環(huán)境下的堆棧

關(guān)于gdb查看棧參考: GDB查看棧信息

關(guān)于gdb調(diào)試可以參考:GDB調(diào)試--以匯編語言為例

 GDB 進(jìn)行調(diào)試 使用心得   

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
深入理解C語言的函數(shù)調(diào)用過程
深度剖析函數(shù)四個(gè)部分(返回值,參數(shù),函數(shù)名,函數(shù)體)
常用的匯編指令都有哪些?
C語言函數(shù)調(diào)用棧(一)
對(duì)gcc編譯匯編碼解析
[C/C++] 函數(shù)調(diào)用的棧分配
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服