naked 函式呼叫

2021-09-06 08:24:06 字數 1888 閱讀 7658

正常的情況下,我們寫乙個 c/c++ 函式,即使是乙個空函式,編譯器也為我們做了不少的工作,生成了一些「必要」的**。請看下面的函式 (為了說明問題隨便寫的):

int

test()

下面是用 vc6 在 release 方式下編譯後的的反彙編**:

00401000   sub         esp,24h     //

增加堆疊空間存放區域性變數 (24h = 36d,4 位元組對齊,注意這裡沒有為 ireturn 分配空間)

00401003 push esi //

儲存要使用的重要暫存器

00401004 lea eax,[esp+4] //

下面是傳遞 messagebox() 要使用的引數

00401008 push 0

0040100a lea ecx,[esp+8] //

編譯器愚蠢,根本不用 ecx,兩個都是 sztemp,兩次 push eax 不得了

0040100e push eax

0040100f push ecx

00401010 push 0

00401012 mov byte ptr [esp+14h],41h

00401017 mov byte ptr [esp+15h],0

0040101c call dword ptr ds:[40509ch]

//呼叫 messagebox()

00401022 mov esi,eax //

儲存返回值到變數 ireturn 。靠!變數 ireturn 自動使用 esi,編譯器太聰明了:)

00401024

push esi

00401025 call dword ptr ds:[4050a0h] //

呼叫 messagebeep()

0040102b mov eax,esi

//把變數 ireturn 交給 eax 作為返回值

0040102d pop esi

//恢復要使用的重要暫存器

0040102e add esp,24h

//減少堆疊空間

00401031 ret //

堆疊長度減 4 並返回

這段**雖然很精幹 (都能自動使用暫存器來儲存變數了),但是有的時候我們並不需要編譯器提供這些自作主張的** (比如寫驅動程式的時候,不過我還沒遇到過這種情況,呵呵~~),我們希望整個全部函式都是自己親手寫進去的 (bt 呀^o^)。好,請出今天的主角 —— 「naked」(怎麼是**呀?),歡迎!visual c++ 的擴充套件關鍵字 naked 允許我們完全定製乙個函式,廢話不說了,看例子 (熬夜寫的 zzzzzz~~):

__declspec(naked) int

test()

}

上面的**是使用的 vc 的內聯彙編,和 vc 編譯後生成的**完全是一樣的 (很有完全控制的成就感吧^_^)。上面我們並沒有又節省什麼 (節省的 push ecx 並不是 naked 的功勞),但是有的時候確實需要的 (舉不出例子來了,倒!)。最後隨便說說注意事項: 

1.使用 naked 關鍵字需要自己構建 ebp 引數指標 (如果用到了 ebp 作為引數指標的話);

2.必須自己使用 ret 或 ret n 指令返回 (除非你不返回)。

系統呼叫 函式呼叫

linux下對檔案操作有兩種方式 提供了庫函式,如open close read write ioctl 等,需包含標頭檔案unistd.h。以write 函式為例 其函式原型為size t write int fd,const void buf,size t nbytes 其操作物件為檔案控制代碼...

python3呼叫函式函式 呼叫函式

python內建了很多有用的函式,我們可以直接呼叫。也可以在互動式命令列通過help abs 檢視abs函式的幫助資訊。呼叫abs函式 abs 100 abs 20 abs 12.34 12.34 呼叫函式的時候,如果傳入的引數數量不對,會報typeerror的錯誤,並且python會明確地告訴你 ...

mysql 過程呼叫函式 mysql函式呼叫過程

1.conn mysql init null 初始化 mysql conn 2.mysql real connect conn,localhost root 123456 xpy 0,null,client found rows 失敗 null 建立乙個連線 3.res mysql query co...