x86 反彙編/變數示例
你能說出以下訪問器方法的原始 C++ 原始碼大致是什麼樣的嗎?
push ebp
mov ebp, esp
mov eax, [ecx + 8] ;THISCALL function, passes "this" pointer in ecx
mov esp, ebp
pop ebp
ret
我們不知道類名,因此我們將使用一個通用的名稱 MyClass(或者您想稱呼它為任何名稱)。我們將列出一個簡單的類定義,它在偏移量 +8 處包含一個數據值。偏移量 +8 是唯一被訪問的資料值,因此我們不知道前 8 個位元組的資料是什麼樣的,但我們將假設(為了我們的目的)我們的類看起來像這樣
class MyClass
{
int value1;
int value2;
int value3; //offset +8
...
}
然後我們將建立我們的函式,我將它命名為“GetValue3()”。我們知道被訪問的資料值位於 [ecx+8] 處(我們在上面定義為“value3”)。此外,我們知道資料正在被讀入一個 4 位元組暫存器 (eax) 中,並且沒有被截斷。因此,我們可以假設 value3 是一個 4 位元組的資料值。我們可以使用 **this** 指標作為儲存在 ecx 中的指標值,並且我們可以從該指標(value3)獲取位於偏移量 +8 處的元素。
MyClass::GetValue3()
{
return this->value3;
}
**this** 指標在這裡不是必需的,但我仍然使用它來說明變數是如何作為 **this** 指標的偏移量被訪問的。
**注意**:請記住,我們不知道類中前 8 個位元組實際上是什麼樣的,我們只有一個訪問器方法,它只訪問偏移量 +8 處的單個數據值。該類也可以看起來像這樣
class MyClass /*Alternate Definition*/
{
byte byte1;
byte byte2;
short short1;
long value2;
long value3;
...
}
或者,任何其他 8 位元組的組合。
你能說出以下設定器方法的原始 C++ 原始碼大致是什麼樣的嗎?
push ebp
mov ebp, esp
cmp [ebp + 8], 0
je error
mov eax, [ebp + 8]
mov [ecx + 0], eax
mov eax, 1
jmp end
:error
mov eax, 0
:end
mov esp, ebp
pop ebp
ret
這段程式碼看起來有點複雜,但不要驚慌!我們將慢慢地一步一步地進行。前兩行程式碼設定了堆疊幀。
push ebp
mov ebp, esp
接下來的兩行程式碼將 [ebp + 8](我們知道它是第一個引數)的值與零進行比較。如果 [ebp+8] 為零,函式跳轉到標籤“error”。我們看到標籤“error”將 eax 設定為 0,並返回。我們以前沒有見過它,但這看起來很像一個 **if** 語句。“如果引數為零,則返回零”。
另一方面,如果引數不為零,我們將值移入 eax,然後將值移入 [ecx + 0],我們知道它是 MyClass 中的第一個資料欄位。我們還從這段程式碼中看到,這個第一個資料欄位必須是 4 個位元組長(因為我們使用的是 eax)。在我們將 eax 移入 [ecx + 0] 之後,我們將 eax 設定為 1,並跳轉到函式的結尾。
如果我們使用與上面問題 1 中相同的 MyClass 定義,我們可以為我們的函式“SetValue1(int val)”獲得以下程式碼。
int MyClass::SetValue1(int val)
{
if(val == 0) return 0;
this->value1 = val;
return 1;
}
請注意,由於我們在失敗時返回 0,在成功時返回 1,因此該函式看起來像具有 **bool** 返回值。但是,返回值是 4 個位元組寬(使用的是 eax),但 **bool** 的大小是特定於實現的,因此我們不能確定。**bool** 通常被定義為具有 1 個位元組的大小,但它通常以與 **int** 相同的方式儲存。