久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2756|回復: 0
收起左側

總結-c語言與匯編

[復制鏈接]
ID:107189 發表于 2016-3-5 17:02 | 顯示全部樓層 |閱讀模式
1. c語言的函數調用與對應的匯編代碼 1.1 調用規則
比如調用函數 function(parameter1, parameter2, parameter3)
Pascal調用規則
_cdecl調用規則
_stdcall調用規則
PUSH     parameter1
PUSH     parameter2
PUSH     parameter3
CALL      function
PUSH     parameter3
PUSH     parameter2
PUSH     parameter1
CALL      function
ADD       ESP, 0CH
PUSH     parameter3
PUSH     parameter2
PUSH     parameter1
CALL      function
參數從左到右傳遞壓棧,由被調用函數清理堆棧 參數從右到左傳遞壓棧,由調用函數負責清理堆棧 參數從右到左傳遞壓棧,由被調用函數負責清理堆棧
用于Win16平臺
C/C++調用標準
Windows API 使用


1.2 匯編代碼 對調用的方式,舉一個例子,對c語言常用的printf:

printf(“%d", a);
解析成匯編代碼如:
PUSH  a
PUSH  OFFSET String "%d"
CALL  printf
ADD ESP, 8

CALL指令和RET指令
段內調用
對CALL指令來說,其執行的步驟一般包括:
  • 將IP壓入棧(即寄存器EIP的值,指向CALL指令之后的第一條指令)
  • 將IP置為跳轉到的地址,開始執行

對應 的RET指令為:
  • IP出棧
  • 執行下一條指令

段間調用
如果是段間函數調用,則CALL的執行過程一般是:


  • 將CS(段地址)壓入棧
  • 將IP(即EIP的值)壓入棧
  • 將IP置為跳轉到的函數地址,開始執行
對應的RET指令執行步驟:
  • IP出棧
  • CS出棧
  • 執行下一條指令


被調用函數的執行步驟
PUSH  EBP ; 保存當前堆棧基址ebp,以作返回用
MOVE EBP, ESP ; 將當前esp的值賦給ebp,作為新的基址,即進入函數內部
SUB ESP, 0CCH ; 將esp往下移動一個范圍,開辟一片新的堆棧空間給當前函數使用
; 這是由于堆棧從高地址往低地址增長,所以,減一個值意味著開辟了
; 新的空間
................. ; 保存其他寄存器的值
.................
................. ; 恢復壓棧的其他寄存器的值
MOVE ESP, EBP ; 恢復esp的值為原來的堆棧棧頂值
POP EBP ; 恢復堆棧基址為原基址位置
RET

一般來說,函數的返回值會放在EAX寄存器中返回。

2. c語言特殊語句塊的匯編代碼
1)For循環的匯編代碼模板
mov <循環變量>, <初始值> ; 循環變量賦初值
jmp B ; 直接跳轉到循環控制測試部分代碼
A: (改動循環變量) ; 修改循環變量值的部分代碼
......
B: cmp <循環變量>, <限制變量> ; 將循環變量的值進行測試、跳轉
jge 跳出循環 ; 符合終止條件,則跳出循環體 ; (注意,這里的jl指令可以是其他的jge等,一具判斷條件而定)
(循環體代碼) ; 否則,進入循環體代碼執行
...
jmp A ; 循環體結束的最后,是一個無條件跳轉語句,調回直接
; 修改循環變量的代碼
2)do循環的匯編代碼模板
A: (循環體) ; 直接是循環體代碼
....
cmp <循環變量>, <限制變量> ; 判斷是否需要終止循環
jl <循環開始處> ; 如果不符合終止條件,直接調回循環體開始處繼續執行循環體
; 代碼(注意,這里的jl指令可以是其他的jge等,一具判斷條件而定)


3) while循環的匯編代碼模板
A: cmp <循環變量>, <限制變量> ; 先比較循環變量,是否需要進行循環
jge B ; 如果滿足停止循環,則直接跳到B,即循環體后的第一個指令
(循環體)
……
jmp A ; 循環體的最后一條指令,是無條件跳轉到循環控制判斷指令A處
B: (循環結束了)

4)if-else的匯編代碼模板(待續...)
理解調用棧最重要的兩點是:棧的結構,EBP寄存器的作用。

首先要認識到這樣兩個事實:
   1、一個函數調用動作可分解為:零到多個PUSH指令(用于參數入棧),一個CALL指令。CALL指令內部其實還暗含了一個將返回地址(即CALL指令下一條指令的地址)壓棧的動作。
   2、幾乎任何本地編譯器都會在每個函數體之前插入類似如下指令:PUSH EBP; MOV EBP ESP;
即,在程序執行到一個函數的真正函數體時,已有以下數據順序入棧:參數,返回地址,EBP。
   由此得到類似如下的棧結構(參數入棧順序跟調用方式有關,這里以C語言默認的CDECL為例):

+| (棧底方向,高位地址) |
| ....................|
| ....................|
| 參數3                |
| 參數2                |
| 參數1                |
| 返回地址             |
-| 上一層[EBP]         |
| 局部變量1            |
| 局部變量2            |
|.....................|

   補充:棧一直隨著函數調用的深入,一直想棧頂方向壓下去。每次調用函數時候,先壓函數參數(從右往左順序壓),再壓入函數調用下條指令的地址(由call完成)。接著進入調用函數體中先執行PUSH EBP; MOV EBP ESP;(一般已經由編譯器加入到函數頭中了),接著就是吧函數體中的局部變量壓入棧中。再遇到函數的調用的嵌套則依此類推。(added by smsong)

  “PUSH EBP”“MOV EBP ESP”這兩條指令實在大有深意:首先將EBP入棧,然后將棧頂指針ESP賦值給EBP。“MOV EBP ESP”這條指令表面上看是用ESP把EBP原來的值覆蓋了,其實不然——因為給EBP賦值之前,原EBP值已被壓棧(位于棧頂),而新的EBP又恰恰指向棧頂。
   此時EBP寄存器就已處于一個很重要的地位,該寄存器中存儲著棧中的一個地址(原EBP入棧后的棧頂),從該地址為基準,向上(棧底方向)能獲取返回地址、參數值,向下(棧頂方向)能獲取函數局部變量值,而該地址處又存儲著上一層函數調用時的EBP值!
   一般而言,ss:[ebp+4]處為返回地址,ss:[ebp+8]處為第一個參數值(最后一個入棧的參數值,此處假設其占用4字節內存),ss:[ebp-4]處為第一個局部變量,ss:[ebp]處為上一層EBP值。
    由于EBP中的地址處總是“上一層函數調用時的EBP值”,而在每一層函數調用中,都能通過當時的EBP值“向上(棧底方向)能獲取返回地址、參數值,向下(棧頂方向)能獲取函數局部變量值”。
如此形成遞歸,直至到達棧底。這就是函數調用棧。
編譯器對EBP的使用實在太精妙了。
從當前EBP出發,逐層向上找到任何的EBP是很容易的:
unsigned int _ebp;
__asm _ebp, ebp;
while (not stack bottom)
{
    //...
    _ebp = *(unsigned int*)_ebp;
}
假如要寫一個簡單的調試器的話,注意需在被調試進程(而非當前進程——調試器進程)中讀取內存數據
8個通用寄存器:
      數據寄存器:AX,BX,CX,DX
      指針寄存器:SP(堆棧指針),BP(基址指針)
      變址寄存器:SI(原地址),DI(目的地址)
1、通用寄存器
數據寄存器,指針寄存器和變址寄存器統稱為通用寄存器。這些寄存器除了各自專門用途外,它們均可用于傳送和暫存數據,可以保存算術邏輯運算中的操作數和運算結果。
(1)數據寄存器
數據寄存器主要用來保存操作數或運算結果等信息,它們的存在節省了為存取操作數所需占用總線和訪問存儲器的時間。
(2)變址和指針寄存器
變址和指針寄存器主要用于存放某個存儲單元地址的偏移,或某組存儲單元地址的偏移,即作為存儲器(短)指針使用。作為通用寄存器,它們可以保存16位算術邏輯運算中的操作數和運算結果,有時運算結果就是需要的存儲單元地址的偏移。
2、控制寄存器(2個)
(1)指令指針寄存器
8086/8088CPU中的指令指針IP也是16位的。
指令指針IP給出接著要執行的指令在代碼段中的偏移。
(2)標志寄存器
8086/8088CPU中有一個16位的標志寄存器,包含了9個標志,主要用于反映處理器的狀態和運算結果的某些特征。6個條件標志+3個方向標志
3、段寄存器(4個)
8086/8088CPU依賴其內部的四個段寄存器實現尋址1M字節物理地址空間。
8086/8088把1M字節地址空間分成若干邏輯段,當前使用的段值存放在段寄存器中。
由于8086/8088有這四個段寄存器,所以有四個當前使用段可以直接存取,這四個當前段分別稱為代碼段,數據段,堆棧段和附加段。
(1)代碼段
(2)數據段
(3)堆棧段
(4)附加段


回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久国产成人 | 一级毛片在线看 | 91精品国产综合久久久久久首页 | 欧美一区二区三区视频 | 亚洲 日本 欧美 中文幕 | 亚洲人成网亚洲欧洲无码 | 一级黄色片美国 | 玖玖综合在线 | 日韩久久久久久久久久久 | 亚洲一区二区三区乱码aⅴ 四虎在线视频 | 中文字幕高清 | 欧美美女爱爱 | 欧美国产视频一区二区 | 亚洲成人一区二区 | 日韩精品免费在线 | www视频在线观看 | 久久亚洲二区 | 91精品国产91久久久久久吃药 | 欧洲亚洲精品久久久久 | 欧美日韩一区二区视频在线观看 | 日日草夜夜草 | 一区二区免费 | 中文一区二区 | 国产欧美精品一区二区 | 久久精品中文字幕 | 欧美精品久久 | 亚洲精品久久久久avwww潮水 | 先锋资源网站 | 国产精品特级片 | 91精品国产综合久久久亚洲 | 亚洲国产网 | 国产成人久久精品 | avhd101在线成人播放 | 不卡的av电影 | 欧美一区二区三区 | 97中文视频 | 欧美精品一区二区三区在线四季 | 国产成人精品免费 | 国产精品久久久久久亚洲调教 | 在线中文一区 | 国产精品a久久久久 |