《組合語言》王爽,學習筆記(子程式呼叫)
在棧的那裡已經簡單提到了子程式的呼叫的實質,就是修改CS:IP,在這裡就詳細介紹一下子程式呼叫的過程。
1.call,ret,retf指令
call,ret和retf是彙編為子程式呼叫而專門設計的彙編指令,CPU在執行ret和retf指令時,利用的棧中的資料,ret只修改IP的值,實現近轉移(段內),而retf修改CS和IP的值(預設CS存在棧中的高位地址),實現遠轉移(段間)。
CPU在執行ret指令時,進行下面操作,用匯編語法解釋就是:
pop IP ;將棧頂元素的值賦值給IP,把棧頂向下移動兩個位元組(刪除原棧頂)
而CPU在執行retf指令時,進行下面操作,用匯編語法解釋就是:
pop IP ;把棧頂元素值賦值給IP,把棧頂向下移動兩位元組
pop CS ;把新棧頂元素複製給CS,再次將棧頂向下移動兩位元組
CPU在執行call指令時,進行兩步操作,(1)將當前的IP或CS與IP壓入棧中,(2)jmp標號處
call實現轉移的方法和jmp原理相同,call分為兩種(不含短轉移,因為call操作需要用到棧,而對棧的操作是預設16位的),近轉移,遠轉移。
call 標號 ;相當於執行push IP,jmp near prt 標號
call far prt 標號 ;相當於執行push CS,push IP,jmp far prt 標號
體會一下call和ret指令利用棧的理由,在思考一下C語言中的遞迴演算法,是不是能深刻了解遞迴中函式的返回過程了?不斷call函式,然後就把IP不斷壓入棧中,最後返回時,不斷popIP,就完成了逐級返回。
2.暫存器衝突
在這之前,已經提到過暫存器衝突的問題了(CX的迴圈問題),現在介紹的是一種標準的呼叫函式的過程。
因為我們CPU中的暫存器是有限的,所以你的子函式也難免會利用到你父函式中使用的暫存器,那麼為了解決這類問題,組合語言在編寫子函式一般使用以下框架:
(1)子程式開始:將父程式的所有暫存器入棧。
(2)子程式內容
(3)子程式結束:將暫存器出棧恢復
(4)ret,retf返回
因為利用到了棧,所以子程式中改變的暫存器的值並不會影響到父程式(除非你在子程式中直接修改棧中內容),這也就更加深刻的解釋了C語言中傳參的問題,為什麼實參無法影響到形參。
日後如果碰到彙編程式一開頭就在不斷push一些暫存器,那麼這接下來的程式就很可能是子函式了。
相關文章
- 《組合語言》王爽,學習筆記(標誌暫存器下)組合語言筆記
- 讀書寫筆記-王爽《組合語言》筆記組合語言
- 讀書筆記:組合語言(王爽)實驗七筆記組合語言
- 組合語言學習筆記組合語言筆記
- 組合語言學習筆記(十二)-浮點指令組合語言筆記
- 組合語言-學習記錄(二)組合語言
- 組合語言零基礎入門學習筆記(一)組合語言筆記
- 組合語言學習筆記03——暫存器(CPU工作原理)組合語言筆記
- 【R語言學習筆記】探索ggplot的排列組合(一)R語言筆記
- 組合語言學習記錄--第一個彙編程式組合語言
- 【學習筆記】組合數學筆記
- 組合數學學習筆記筆記
- 【R語言學習筆記】探索ggplot的排列組合:線圖(一)R語言筆記
- 組合語言學習記錄--輸入輸出字串組合語言字串
- Solidity語言學習筆記————32、建立合約Solid筆記
- c語言程式基礎學習筆記C語言筆記
- C 語言學習筆記筆記
- C語言學習筆記C語言筆記
- 組合最佳化 學習筆記筆記
- Solidity語言學習筆記————35、抽象合約和介面Solid筆記抽象
- Solidity語言學習筆記————23、函式呼叫和賦值Solid筆記函式賦值
- 【C++學習筆記】型別組合C++筆記型別
- Solidity語言學習筆記————13、固定大小位元組陣列Solid筆記陣列
- Solidity語言學習筆記————14、動態位元組陣列Solid筆記陣列
- 組合數學筆記-排列與組合筆記
- 組合語言1 - 什麼是組合語言?組合語言
- 熱更新語言--lua學習筆記筆記
- c語言學習筆記===函式C語言筆記函式
- 《JavaScript語言精粹》學習筆記二JavaScript筆記
- 《JavaScript語言精粹》學習筆記一JavaScript筆記
- R語言學習筆記之一R語言筆記
- Go 基礎語言學習筆記Go筆記
- 組合語言組合語言
- acm-排列組合學習筆記(更新中)ACM筆記
- MySQL學習筆記:組合索引-最左原則MySql筆記索引
- MySQL學習筆記:組合索引-索引下推MySql筆記索引
- Per語言入門第4版學習筆記-第四章子程式R語言筆記
- Solidity語言學習筆記————44、合約的後設資料Solid筆記