《課堂筆記》
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 %ebp2 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 表...