「C++反彙編系列一」 彙編基礎知識

「反彙編系列主要是在linux平臺下,從彙編層面分析c++ 的數據類型、函數調用、返回值、分支、循環等底層原理,希望對大家有幫助~」

【目錄】

1-------------x64 中常用的寄存器

2-------------彙編語言中的基本尋址方式

2.1 --------數據尋址方式


要對c++程序進行反彙編分析學習,需要一定的彙編知識,所以這裡就跟大家一些簡單學習下我們後面序列文章所需的知識點。

  1. Intel 指令組成

intel指令主要由以下6部分組成


「C++反彙編系列一」 彙編基礎知識

Fig 1


  1. x86_64 中常用的寄存器


「C++反彙編系列一」 彙編基礎知識

Fig 1


上圖中說明了各個寄存器的用途以及是否是保留它用(上面的蝌蚪文通俗易懂),這裡就不再翻譯贅述了。

  1. 彙編語言中的基本尋址方式

2.1 數據尋址方式

彙編語言中的指令操作的數據主要來自寄存器,立即數,內存。

立即尋址:指令所需的操作數直接包含在指令代碼中,就是常說的立即數
且只能出現在源操作數位置直接尋址操作數來源於(指令中直接指出的地址所指向的內存)
MOV AX [2000H],這個方括號的意思是“以括號內的值作為地址,(所指向的內存)中存儲的值”
MOV AX,x這裡的這個x是之前在數據段定義的變量,當彙編程序被彙編時,彙編器會計算出x的偏移值,然後替換掉原來的x


所以在DEBUG模式下,看到的就不是變量名,而是變量名在數據段中的偏移地址寄存器尋址操作數來源於某個寄存器/是這個寄存器裡存儲的值
比如我要把某個16位的數從BX複製到AX,那麼我可以用MOV AX,BX
這裡的兩個操作數都是寄存器尋址寄存器間接尋址這就很好理解了,現在括號裡放的不是立即數了,放的是寄存器了,代表操作數在內存中,它的地址的括號內的寄存器中
不過這個間接尋址有幾個注意點:
1. 寄存器一般使用的是基址寄存器BP\\BX或變址寄存器SI\\DI
2. 完整的形式應該是[段地址]:[段內偏移]
3. 當未顯式指定段寄存器時,BX\\SI\\DI中是相對於DS段的偏移地址,BP是相對於SS段的偏移地址寄存器相對尋址操作數的地址 = 間址寄存器+偏移量
同直接尋址一樣,偏移量可以是一個常量也可以是一個符號名或變量名
例如MOV AX,[SI+10H]或MOV AX,ARRAY[SI]基址變址尋址操作數地址 = 基址寄存器+變址寄存器
例如MOV AX,[BX+SI]

2.與轉移地址有關的尋址方式

這四種尋址方式主要運用於轉移指令JMP和過程調用指令CALL
首先要了解這兩個東西:


標號,過程名(自己看,不講了)

尋址方式講解段內直接就是說我們現在程序運行到這裡需要發生一個轉跳
去執行其他地方的一些代碼
辣麼這些代碼在哪裡呢
我們進行了一些運算,用當前IP的值加上指令中指定的偏移量,得到了一個地址
然後我們就要跳到那裡去
比如JMP func1
偏移量可以是8位或者16位,相對的我們就要使用 SHORT func1或者NEAR PTR func1段間直接這個和段內直接的區別是什麼呢
就是一個X86彙編程序,可能有幾個代碼段,當使用段間直接尋址時,需要改變段地址的值,相當於跳到了另一個代碼段,開始執行新的代碼
比如JMP FAR PTR func1段內間接跟段內直接的區別是:要轉跳的地址放在了寄存器裡,而不是一個標號(參考一下2裡的寄存器簡介尋址吧)段間間接類似於段內間接,但是,間接尋址的地址不能直接放在寄存器裡,只能放在內存單元中,而且是一個雙字


分享到:


相關文章: