20170226 由GCC彙編理解程式呼叫

2021-07-27 21:35:44 字數 1949 閱讀 6846

《課堂筆記》

1.堆疊/棧:如何被cpu維護,函式呼叫需要用到堆疊

2.暫存器:記憶體中的資料需要讀入暫存器才能被cpu計算,

常用的暫存器eax/ebx/ecx/edx為通用暫存器

ebp:當前棧幀的開始處(若干函式呼叫形成乙個堆疊,其中乙個元素為乙個棧幀)

esp:指向函式棧的棧頂

ebp/esp暫存器只有乙個,函式呼叫需要儲存現場就要把ebp入棧

3.gcc 彙編指令(att語法)

4.從硬碟到記憶體(程序的虛擬記憶體空間)

5.push ebp 導致  esp自動減4,棧生長,pop ebp導致 esp+4,棧收縮

6.無法判斷記憶體存放的是值還是位址,只有程式知道

c語言實現:

int demo()
int add(int *xp, int *yp)
gcc 彙編呼叫者demo

1 pushl %ebp //把ebp的值放到棧頂,同時esp-4,棧生長

2 movl %esp %ebp//

3 subl %24 esp//把esp值減去24個位元組,相當於為函式分配了記憶體空間。esp=776

4 movl $10 -4(%ebp) //$10表示立即數,把數字10存放到ebp值-4的記憶體位址中

5 movl $20 -8(%ebp) //把數字20存放到ebp值-8的記憶體位址中

6 leal -8(%ebp) %eax//把ebp存放的位址-8 放到 eax暫存器,實際上就是指向

7 movl %eax 4(%esp) //把792 放到esp+4的記憶體位址

8 leal -4(%ebp) %eax

9 movl %eax (%esp)//6-9行實際上實現了對x,y的指標

10 call add//進入對add函式的呼叫

11 列印結果(略)--位址是100

被呼叫者函式add

1 push %ebp

2 movl %esp %ebp

3 pushl %ebx//儲存現有的值,該儲存器將要使用,intel約定,eax,ecx,edx暫存器呼叫者儲存,ebx由被呼叫者儲存

4 movl 8(%ebp) %edx//思考:到此edx的值是多少? ebp=768+8=776,addr776 value=796

5 movl 12(%ebp) %ecx//思考:到此ecx的值是多少? ebp=768+12=780,addr780 value=782

6 movl (%edx) %ebx//把ebx中位址的值放入ebx,根據位址從記憶體中取值

7 movl (%ecx) %eax//把ecx中位址的值放入eax,根據位址從記憶體中取值

8 add %ebx %eax 

9 popl %ebx

10 popl %ebp

11 ret

GCC嵌入彙編

其中有一段精華如下 嵌入式彙編的一般形式 asm volatile output input modify 其中,asm 表示彙編 的開始,其後可以跟 volatile 這是可選項 其 含義是避免 asm 指令被刪除 移動或組合 然後就是小括弧,括弧中的內容是我們介 紹的重點 為彙編指令部分,例如,...

GCC內聯彙編

有時為了高效,有時為了直接控制硬體,有些模組我們不得不直接用組合語言來編寫,並且對外提供呼叫的介面,隱藏細節,這其實就是內聯彙編。如何使用內聯彙編?我們就以 gcc 為例,一窺其中奧秘!一 關鍵字 如何讓 gcc 知道 中內嵌的彙編呢?借助 關鍵字!來看下面的例子 asm volatile hlt ...

gcc內聯彙編

有時為了高效,有時為了直接控制硬體,有些模組我們不得不直接用組合語言來編寫,並且對外提供呼叫的介面,隱藏細節,這其實就是內聯彙編。如何使用內聯彙編?我們就以 gcc 為例,一窺其中奧秘!一 關鍵字 如何讓 gcc 知道 中內嵌的彙編呢?借助關鍵字!來看下面的例子 a volatile hlt a 表...