2015-10-22 38 views
0

我花了很多時間試圖解決這個問題,我不明白,爲什麼它不工作。問題的描述是在下面的評論:註冊ESI導致RunTime-Check失敗#0錯誤

.386 
.MODEL FLAT, STDCALL 

OPTION CASEMAP:NONE 
.NOLIST 
.NOCREF 
INCLUDE \masm32\include\windows.inc 
.LIST 

.CODE 
DllEntry PROC hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD 
mov eax, TRUE 
ret 
DllEntry ENDP 

caesarAsm proc string: DWORD, key: DWORD, stringLength : DWORD 

     mov esi, 1 ; I cannot use this register, mov esi, (anything) causes Crash: 
     ; Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention 
     mov eax, string 
     ret 
caesarAsm endp 
END DllEntry

我搜索「整」的互聯網,我發現問題與堆棧連接,但沒有堆棧操作幫我解決這個問題。 我正在使用Microsoft Visual Studio 2012

+0

https://en.wikipedia.org/wiki/X86_calling_conventions#Register_preservation –

回答

1

我假設這個函數沒有發生錯誤,而是在別處觸發。 esi寄存器是一個被調用者保存的寄存器。您必須確保它在函數出口處的值與入口時的值相同。你可以在你的函數中使用它,但是你必須保存和恢復它的值。如:

push esi 
    mov esi, 1 
    mov eax, string 
    pop esi 
    ret 

這都是有據可查的。您只能使用eaxecxedx而不保存。注意:您正在使用匯編程序的高級功能,您可能需要檢查實際生成的代碼,或者直到您確信結果將會發生變化之前,不要使用它們。順便提一句masm有一個USES關鍵字,它會爲你做保存/恢復。