2016-12-08 43 views
0

可以說我有一個PROC在我的彙編代碼如下所示:動態變量在程序集中創建? (x86彙編)

.CODE 
PROC myProc 
MOV EAX, 00000001 
MOV EBX, 00001101 
RET 
ENDP myProc 

我想MOV 1,進入EAX寄存器,並移動13到在我的程序EBX寄存器,但是我想要爲我的PROC創建兩個局部變量,將var的值賦值爲1,並將var b的值賦值爲13,然後從那裏將[a]移動到EAX,將[b]賦值給EBX。我以前有過這個想法很多,也許是堆棧變量,或者類似的東西上創造空間:

.CODE 
PROC myProc 
PUSH ESP 
PUSH EBP 
MOV ESP, 00000001 
MOV EBP, 00001101 
MOV EAX, [ESP] 
MOV EBX, [EBP] 
ENDP myProc 

但是,這仍然還真不是動態可變的創作,我只是寫入和讀取數據備份和在寄存器之間。所以本質上我想弄清楚如何在運行時在程序集中創建變量。我將不勝感激任何幫助。

+0

你的第二個例子是廢話。如果您爲堆棧指針指定了一個常量,那麼您已經失去了對ESP和EBP所在位置的唯一引用。另外,'mov eax,[001]'會在錯誤的地址上發生故障。在第二個例子中,我也沒有看到任何寄存器到寄存器的移動,所以IDK認爲它的確如此,但它不是「*在寄存器之間來回寫入數據。」 –

+0

如果你想要動態存儲空間用於存儲一些值,對於小尺寸的東西(高達幾kiB),通常可以在堆棧中預留該空間,這就是C所做的。在PROC開始時,一個序言指令可能是'sub esp,',並且在'ret'之前你可以恢復'esp'(釋放該空間)。在這兩者之間,你可以通過'[esp + <0 .. size-1 offset>]來解決它,儘管通常使用'ebp'。如果你想要巨大的(kiB-> MiB/GiB)動態內存空間,請檢查你的API堆分配。 *「變量」* =>隨意調用它,不重要。 – Ped7g

回答

3

變量是一個高級概念。一個C函數的asm實現通常會在一段時間內在一個寄存器中生存一個變量,但也可能在其他時間生存在一個不同的寄存器中,或者在某個位置的內存中不再需要它(或者你用完了的寄存器)。

在ASM你真的沒有變量(除了靜態存儲等),除非使用註釋來跟蹤什麼意思。只需移動數據併產生有意義的結果即可。

儘可能避免內存。看看C編譯器的輸出:任何體面的編譯器都會盡可能地將所有內容保存在寄存器中。

int foo(int a, int b) { 
    int c = a + 2*b; 
    int d = 2*a + b; 
    return c + d; 
} 

此功能編譯與gcc6.2 -O3 -fverbose-asmon the Godbolt compiler explorer)以下的32位代碼。注意gcc如何將變量名稱附加到帶有註釋的寄存器。

mov  ecx, DWORD PTR [esp+4] # a, a 
    mov  edx, DWORD PTR [esp+8] # b, b 
    lea  eax, [ecx+edx*2] # c, 
    lea  edx, [edx+ecx*2] # d, 
    add  eax, edx # tmp94, d 
    ret 
+0

非常感謝你。我非常感謝大家幫助我,讓我更好地理解這一點! –

1

看起來好像你正在使用MASM語法。該標準MASM的方法來創建本地變量是

.CODE 
    PROC myProc 
    LOCAL a: DWORD 
    LOCAL b: DWORD 
    ; Initialize those vars 
    MOV a, 00000001 
    MOV b, 00001101 
    RET 
    ENDP myProc 

LOCAL指示堆棧使用EBP相對索引變量上創建空間。

+0

我認爲你至少應該提到高級語言變量的概念也可以映射到寄存器,因爲避免首先出現溢出是更好的辦法。 –