国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

C語言的那些小秘密之堆棧

發布時間:2016-2-19 09:06    發布者:designapp
關鍵詞: C語言 , 堆棧

在講解堆棧之前,我們先要來說說其實我們常說的堆棧是兩種數據結構。那么什么是堆什么又是棧呢?
棧,是硬件。主要作用表現為一種數據結構,是只能在某一端插入和刪除的特殊線性表。它按照后進先出的原則存儲數據,先進入的數據被壓入棧底,最后的數據在棧頂,需要讀數據的時候從棧頂開始彈出數據(最后一個數據被第一個讀出來)。棧是允許在同一端進行插入和刪除操作的特殊線性表。允許進行插入和刪除操作的一端稱為棧頂(top),另一端為棧底(bottom);棧底固定,而棧頂浮動;棧中元素個數為零時稱為空棧。插入一般稱為進棧(PUSH),刪除則稱為退棧(POP)。 棧也稱為先進后出表。棧可以用來在函數調用的時候存儲斷點,做遞歸時要用到棧!
以上定義是在經典計算機科學中的解釋。
在計算機系統中,棧則是一個具有以上屬性的動態內存區域。程序可以將數據壓入棧中,也可以將數據從棧頂彈出。在i386機器中,棧頂由稱為esp的寄存器進行定位。壓棧的操作使得棧頂的地址減小,彈出的操作使得棧頂的地址增大。
棧在程序的運行中有著舉足輕重的作用。最重要的是棧保存了一個函數調用時所需要的維護信息,這常常稱之為堆棧幀或者活動記錄。堆棧幀一般包含如下幾方面的信息:
1. 函數的返回地址和參數
2. 臨時變量:包括函數的非靜態局部變量以及編譯器自動生成的其他臨時變量。
堆,是一種動態存儲結構,實際上就是數據段中的自由存儲區,它是C語言中使用的一種名稱,常常用于動態數據的存儲分配。堆中存入一數據,總是以2字節的整數倍進行分配,地址向增加方向變動。堆可以不斷進行分配直到沒有堆空間為止,也可以隨時進行釋放、再分配,不存在次序問題。
堆和棧在使用時相向生長,棧向上生長,即向小地址方向生長,而堆向下增長,即向大地址方向,其間剩余部分是自由空間。使用過程中要防止增長過度而導致覆蓋。
一般的程序我們都是使用小內存模式。
明白了堆和棧的概念之后我們來看一個面試的c語言題目。代碼要相關要求如下所示:
#include
using namespace std;
void print()
{
//這里進行打印arr數組,print不準傳參數
}
int main()
{
int s=0;
int ss=0;
char *str="fdsafdsafdsafdsafdsafdsafdsa";
char fdsa='f';
char srt[8];
int arr[]={32,43,3,567,987,21,56};//數值隨即
print();
return 0;
}
剛剛一開始看到這個題目時,你可能有點發懵,心想可能在不傳遞參數的情況下打印arr數組的內容,但是看看我們的標題就應該知道該題跟棧有關系,在做之前我們先來回顧幾個知識點。
push操作先修改指針,后將信息入棧。
ESP為堆棧指針,棧頂有ESP寄存器來定位。壓棧的操作使得棧頂的地址減小,彈出的操作使得棧頂的地址增大。
EBP是32位的BP,EBP是基址指針,EBP與BP的關系就像AX與AL、AH的關系一樣。BP為基指針寄存器,用它課直接存取堆棧中的數據,他的作用在調用函數時保存ESP,使函數結束時可以正確返回。
c的默認函數壓棧操作為:
參數是從右向左壓棧的,默認四字節對齊,函數里面定義的變量是默認對齊方式----變量首地址是自身結構體里邊最大標準數據類型字節的整數倍。
我們先來看看上面這段代碼的匯編語句:
//*******************************************start*********************************************//
.file "push.c"
.text
.globl print
.type print, @function
print:
pushl %ebp
movl %esp, %ebp
popl %ebp
ret
.size print, .-print
.section .rodata
.LC0:
.string "fdsafdsafdsafdsafdsafdsafdsa"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $64, %esp
movl %gs:20, %eax
movl %eax, 60(%esp)
xorl %eax, %eax
movl $0, 44(%esp)
movl $0, 40(%esp)
movl $.LC0, 36(%esp)
movb $102, 51(%esp)
movl $32, 8(%esp)
movl $43, 12(%esp)
movl $3, 16(%esp)
movl $567, 20(%esp)
movl $987, 24(%esp)
movl $21, 28(%esp)
movl $56, 32(%esp)
call print
movl $0, %eax
movl 60(%esp), %edx
xorl %gs:20, %edx
je .L3
call __stack_chk_fail
.L3:
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
.section .note.GNU-stack,"",@progbits
//*******************************************end*********************************************//
看看上面的匯編代碼,我們的重點放在紅色字體部分,在函數的開頭部分都有這么兩行代碼: pushl %ebp --------------------------->保存上一個函數的棧底
movl %esp, %ebp --------------------------->用來保存當前堆棧指針的值
ebp存放當前函數棧低的地址,就是說ebp可以看做一個指針,指向棧頂,而其實棧頂存放的數據就是上一個函數的ebp的值,即就是main函數的棧底。
                                
               
明白了上面的內容,那么我們就可以實現題目的要求了。代碼如下所示:
#include
using namespace std;
void print()
{
//這里進行排序,print不準傳參數 unsigned int _ebp; __asm{
mov _ebp,ebp
}
int *p=(int *)(*(int *)_ebp-4-4-4-4-8-7*4);
for(int i=0;i


為了強調默認的字節對齊概念,我們再來修改下代碼得到的運行結果可以上面得做一個比較。
代碼如下,紅色部分為修改代碼。
#include
using namespace std;
void print()
{
//這里進行排序,print不準傳參數
unsigned int _ebp;
__asm{
mov _ebp,ebp
}
int *p=(int *)(*(int *)_ebp-4-4-4-4-8-7*4);
for(int i=0;i


如果我們修改了 char srt[6];之后去把int *p=(int *)(*(int *)_ebp-4-4-4-4-8-7*4);修改為int *p=(int *)(*(int *)_ebp-4-4-4-4-6-7*4);,注意紅色部分的對比,運行結果就變為了:


顯然對比可知運行結果出錯了。在此多次一舉的給出對比無非是為了大家能夠對字節的對齊方式加以重視。當然以上內容難免有錯,畢竟c語言博大精深,如果有不正確的地方,請糾正。
本文地址:http://m.qingdxww.cn/thread-160931-1-1.html     【打印本頁】

本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
您需要登錄后才可以發表評論 登錄 | 立即注冊

廠商推薦

  • Microchip視頻專區
  • Dev Tool Bits——使用MPLAB® Discover瀏覽資源
  • Dev Tool Bits——使用條件軟件斷點宏來節省時間和空間
  • Dev Tool Bits——使用DVRT協議查看項目中的數據
  • Dev Tool Bits——使用MPLAB® Data Visualizer進行功率監視
  • 貿澤電子(Mouser)專區

相關視頻

關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕在线精品视频入口一区 | 美国农夫激情在线综合 | 日本-区二区三区免费精品 日本强日本不卡一 | 黄色免费网站观看 | 99热在线这里只有精品 | 亚洲精品第一卡2卡3卡4卡5卡 | 亚洲精品永久www忘忧草 | 一级毛片在线播放免费 | 麻豆国产在线观看免费 | 国产美女在线免费观看 | 天天久久狠狠伊人第一麻豆 | 国内精品91 | 亚洲免费成人网 | 亚洲国产欧美日韩一区二区三区 | 黄页免费在线看 | 丁香婷婷综合网 | 国内一级特黄女人精品片 | 色婷亚洲 | 久久青青草原精品影院 | 国产日韩一区二区三区在线播放 | 国产高清精品一级毛片 | 羞羞视频免费网站 | 日本在线观看免费观看完整版 | 天天插一插 | 国产亚洲精品aa在线看 | 亚洲毛片免费视频 | 国产一区二区三区高清 | 免费的成人a视频在线观看 免费岛国小视频在线观看 免费岛国 | 国产在线播放不卡 | 免费一级在线观看 | 国产99久9在线 | 日本大片在线免费观看 | 国内精品在线播放 | 99久久精品国产一区二区三区 | 国产va免费精品 | 国产日韩精品一区二区在线观看 | 自拍一区在线观看 | 日本午夜网站 | 欧美性精品hd在线观看 | 99爱在线精品视频免费观看9 | 成人亚洲性情网站www在线观看 |