2013-07-25 26 views
1

我想重寫MASM615給我的程序。我只是打算使用「USES」指令,以便我不必執行所有推入和彈出堆棧。這會明顯改變過程中引用的一些地址,因爲它們引用堆棧指針(esp)。我以爲我正確實施它,但程序掛在我身上。該過程應該輸出一個直接寫入代碼流的字符串,然後跳過該字符串,以便CPU不會嘗試將該字符串作爲代碼執行時發生錯誤。下面是我得到的過程:MASM615程序重寫不起作用(想添加「使用」指令)

WritePrompt PROC 
push ebp 
mov ebp, esp   ; set up the ebp pointer 
push esi    ; save used reg 
push eax    ; save used reg 
mov esi, [ebp+4]  ; use ret.addr. as string pointer 

L1: cmp BYTE PTR [esi], 0 ; check for the end of string 
jz L2     ; jump if the string is over 

mov al, [esi]   ; get the next string character 
call WriteChar   ; ... and output it 
inc esi    ; increment the string pointer 
jmp L1 

L2: inc esi    ; adjust the string pointer 
mov [ebp+4], esi  ; modify the return address 

pop eax    ; restore all used regs and exit 
pop esi 
pop ebp 
ret 
WritePrompt ENDP 

這是我得到什麼,下面是我的簡單的重新編寫,使用用途指令跳過堆棧push和pop:

outStr PROC USES eax ebp esi 
mov ebp, esp 
mov esi, [ebp] 

L1: 
cmp BYTE PTR [esi], 0 
jz L2 

mov al, [esi] 
call WriteChar 
inc esi 
jmp L1 

L2: 
inc esi 
mov [ebp], esi 

ret 
outStr ENDP 

這程序在被調用時會導致程序掛起。爲什麼?它出什麼問題了?我覺得我認爲推動和爆發會有所改變。

編輯:添加「call dumpregs」幾個地方進行調試後,發現該程序崩潰的行是「cmp BYTE PTR [esi],0」,這讓我覺得我沒有得到指向字符串從堆棧中正確。使用「mov esi,[ebp + 4]」似乎至少讓我走得更遠,但它立刻跳到L2。

編輯2:

我發現了這個問題。看來我使用的文檔非常不清楚USES指令的用途。它將所有「Used」寄存器堆棧,並在之後彈出它們,就像沒有USES指令一樣。因此,我需要使用的命令是:

mov ebp, esp 
add ebp, 12 
mov esi, [ebp] 

因爲我甚至不能回答我自己的問題還沒有,我想我必須把它放在這裏。此問題已關閉。不管怎麼說,還是要謝謝你!

回答

0

誤解「使用」指令。需要使用代碼來補償推入堆棧的寄存器。

mov ebp, esp 
add ebp, 12 
mov esi, [ebp]