堆棧是什么:
??? 堆棧是內(nèi)存的一種先進后出的存儲方式暗挑,具有由高地址向低地址生長的特質(zhì)世囊。(像是以空氣為地基,往地底建房子一樣窿祥,靠近地心的一層叫做棧頂株憾,懸浮在空氣中的叫做棧底)
為什么要使用堆棧:
??? 寄存器不夠存放所有的局部變量
??? 有些局部變量是數(shù)組或結(jié)構(gòu),因此必須通過數(shù)組或結(jié)構(gòu)引用來訪問
??? 過程會用棧幀來存放它調(diào)用其他過程的參數(shù)
堆棧是怎樣運行的:
??? 以函數(shù)調(diào)用作為引入
函數(shù)調(diào)用
掃盲:
??? 程序的一系列指令本來存在于硬盤中,跑得快的老虎cpu發(fā)一道作業(yè)讓龜硬盤把數(shù)據(jù)運輸?shù)酵米觾?nèi)存中嗤瞎。
??? %ebp墙歪,一直指向當前函數(shù)在一個棧的開始地址。
??? %esp贝奇,隨著指令的運行虹菲,指向函數(shù)幀最后的地址。
過程:???
通俗語言順序描述:
調(diào)用者函數(shù)最開始
“把寄存器ebp的值壓到棧里去”? (pushl??? %ebp)
“把esp的值賦給ebp”(movl??? %esp掉瞳,%ebp)
“把esp的值減去24”(為了開辟冗余的空間)
“把arg2的值放到ebp-4的地址”(leal? -4(%ebp), %eax)
“把arg1的值放到ebp-8的地址”(leal? -8(%ebp), %eax)
“把arg1的地址作為數(shù)據(jù)放到當前esp指向的地址”
“把arg2的地址作為數(shù)據(jù)放到當前esp+4指向的地址”
“把當前函數(shù)下一條指令的地址壓入棧中”(call swap_add)
再次開辟新的函數(shù)幀毕源,執(zhí)行被調(diào)用者過程
“把寄存器ebp的值壓到棧里去”? (pushl? ? %ebp)
“把esp的值賦給ebp”(movl??? %esp,%ebp)
“把esp的值減去24”(為了開辟冗余的空間)
“把ebx的值壓進棧里面”(這是存放被調(diào)用者保存的數(shù)據(jù))
“取出當前esp+8的內(nèi)容即地址到%edx寄存器中”(movl? 8(%ebp), %edx)
“取出當前esp+12的內(nèi)容即地址到%ecx寄存器中”(movl? 12(%ebp),%ecx)
“取出%edx寄存器中的內(nèi)容對應(yīng)的值到%ebx”(movl? (%edx),? %ebx)
“取出%ecx寄存器中的內(nèi)容對應(yīng)的值到%eax”(movl? (%ecx),? %eax)
“寄存器移動賦值陕习,哈哈哈我懶就不寫了霎褐,看匯編代碼就知道了”
結(jié)束函數(shù)調(diào)用后
“彈出%ebx的值,這是調(diào)用者函數(shù)的值该镣,要還給調(diào)用者”(popl?? %ebx)
“把%ebp的值給%esp”(movl? %ebp,? %esp)
“彈出%esp的值到調(diào)用者的棧底冻璃,即%esp又成棧底了”(popl? %ebp)
“返回執(zhí)行上一個函數(shù)的下一條語句”
總結(jié):
(1)把參數(shù)和返回地址準備好,
(2)然后大家都遵循約定损合, 每次新函數(shù)都要建立新的函數(shù)幀:
"把寄存器ebp的值壓到棧里去“
"把esp的值賦給ebp"
(3) 函數(shù)調(diào)用完了省艳, 重置 ebp 和esp ,讓他們重新指向調(diào)用著的棧幀嫁审。
????????????????????????????????????????????????????????????????????????????????????????????????????????????? 本文引用《深入理解計算機系統(tǒng)第三章幀棧結(jié)構(gòu)》《公眾號碼農(nóng)翻身<CPU阿甘:函數(shù)調(diào)用的秘密>》