比方說,我們有以下的C++代碼:定義變量中的C++內聯彙編
int var1;
__asm {
mov var1, 2;
}
現在,想我所知道的是,如果我不想定義__asm指令外VAR1,我需要做些什麼才能把它放進去。它甚至有可能嗎?
由於
比方說,我們有以下的C++代碼:定義變量中的C++內聯彙編
int var1;
__asm {
mov var1, 2;
}
現在,想我所知道的是,如果我不想定義__asm指令外VAR1,我需要做些什麼才能把它放進去。它甚至有可能嗎?
由於
要做到這一點,您需要使用_declspec(裸體)創建一個「裸」方法,並編寫通常由編譯器創建的序言和結語。
一個序言的目的是:
的結語有:
這裏預留空間是一個標準的序言
push ebp ; Save ebp
mov ebp, esp ; Set stack frame pointer
sub esp, localbytes ; Allocate space for locals
push <registers> ; Save registers
和一個標準的結尾處理:
pop <registers> ; Restore registers
mov esp, ebp ; Restore stack pointer
pop ebp ; Restore ebp
ret ; Return from function
你的局部變量將從(ebp - 4)
開始,然後下降到(ebp - 4 - localbytes)
。功能參數將從(ebp + 8)
開始並向上。
它不可能創建彙編一個C變量:C編譯器必須知道有關變量(即,其類型和地址),這意味着它具有在C代碼中聲明。
可以做的是通過C中的extern
聲明訪問彙編程序中定義的符號。這對於具有自動存儲持續時間的變量來說不起作用,儘管這些變量沒有固定的地址,而是相對於基址指針。
如果您不想訪問asm
塊之外的變量,則可以使用堆棧來存儲彙編程序本地數據。請記住,你必須堆棧指針恢復到以前的值在離開asm
塊時,如
sub esp, 12 ; space for 3 asm-local 32bit vars
mov [esp-8], 42 ; set value of local var
[...]
push 0xdeadbeaf ; use stack
[...] ; !!! 42 resides now in [esp-12] !!!
add esp, 16 ; restore esp
如果你不想局部變量的相對地址改變,只要你操作堆棧(即使用push
或pop
),則必須按照cedrou's answer中所述建立堆棧幀(即,將堆棧的基址保存在ebp
中,並將地址相對於此值保存)。
局部變量分配和釋放由通過ESP寄存器操作的調用堆棧上的可用空間,即:
__asm
{
add esp, 4
mov [esp], 2;
...
sub esp, 4
}
一般來說,這是通過建立一個「堆棧幀」爲調用函數更好地處理反而,然後訪問使用偏移局部變量(和功能參數)的框架內,而是採用了ESP直接註冊,即:
__asm
{
push ebp
mov ebp, esp
add esp, 4
...
mov [ebp-4], 2;
...
mov esp, ebp
pop ebp
}
確定子ESP,3會給空間3 32位瓦爾?我的想法是,對於每個32位變量,我必須從esp中取4個變量。 – 2009-09-08 21:47:51
至少C++在內部定義如下:var_4 = dword ptr -4 – 2009-09-08 21:48:27
你是對的 - 不應該在深夜回答問題;) – Christoph 2009-09-08 22:53:44