2014-10-10 17 views
0

在彙編中,'pop'命令用於返回指定的值嗎?我似乎無法使其正常工作。我嘗試打印輸入以查看輸入是否已更改,但是在再次等待用戶輸入之前,程序會循環兩次。在Assey中,我的函數試圖返回一個值是否有問題?

數據聲明:

section .data 
    test db "Test",10 
    testLen equ $-test 

這裏的輸入聲明

section .bss 
input resb 1 

則子程序調用:

section .text 
global _start 

_start: 

sub esp,2 ;this is for the return value 
call function ; call the subprogram 
pop word[input] 

mov eax,4 
mov ebx,1 
mov ecx,input 
mov edx,1 ;1 character input only from user is expected 
int 80h 

mov eax,4 
mov ebx,1 
mov ecx,test 
mov edx,testLen 
int 80h 

jmp _start 

則子程序:

function: 
mov eax,3 
mov ebx,0 
mov ecx,[esp+4] 
mov edx,2 ;of length 2 because only 1 character is expected from user + the \n char 
int 80h 

ret 

我在我的子程序'function'中的掃描程序中做錯了什麼?謝謝你能幫助我的人。剛開始學習Assembly的子程序,我無法弄清楚這個。一直呆在這個簡單的bug現在一個小時。

+0

通常'pop'不用於返回,'mov eax,SOMETHING'是。但是這看起來像手寫的asm,並沒有遵循任何標準的調用約定。 – o11c 2014-10-10 04:20:03

回答

0

好吧,讓我看看我是否猜測你誤解的地方,並幫助你清除它。

你已經聽到了一個被熟悉的東西嘲笑的短語,它會像這樣「該堆棧用於在函數之間傳遞變量。」是的,這是真的;但並不完全正確,它已經讓你的生活充滿困惑。

我還假設你在C和程序集的上下文中思考。

好吧,關於C,函數有一個「類型」,因爲我猜你知道。

對於彙編語言,函數沒有類型。

(我們會堅持使用x86這裏,雖然它一般適用於一堆別人的真)

彙編語言,你有呼叫指令,以及懲戒指令,這是關於它。

哦,是的,你在x86和其他一些類似的芯片上也有Int指令;但就目前而言,我們只會將重點放在致電Ret

所以無論如何,這個BIZ的「堆棧上傳遞參數」是(在C中的至少)約總是設定爲使

  • 參數被傳遞TO堆棧
  • 在功能上
  • 值返回FROM功能在寄存器

我想這就是你的困惑我秒。

我可以看到,你對學習彙編的願望很認真,而且在使用堆棧來傳遞變量時,你是「有創意」的。

誰知道?也許你已經注意到了一種更好的方式(但我認真地懷疑它;使用寄存器來處理你正在嘗試做的事情)

無論如何,如果我正確猜測,你絕不會在堆棧中寫入任何東西你創建的function填充

這是你要做什麼來確認或否認這一點。

調試這個由單在每個這三個指令斷點踩着它...

sub esp,2  ;this is for the return value 
    call function  ; call the subprogram 
    pop word[input] 

打開一個觀察窗口和觀察[ESP]前後call function指令之後的存儲位置。

我想你會發現你從來沒有寫入任何東西到那個位置。

再次,雖然這個概念可能在這種情況下工作,但它通常是一個不太好的想法嘗試;所以省去很多麻煩,並在寄存器中返回一個值。

編譯器就是這麼做的;並只問新的專家:編譯器比人類更聰明(但我離題)

不知道這是否有幫助,但我試過。

0

返回值通常在eax中返回,只有參數和局部變量存儲在堆棧中,但這在調用約定之間會有所不同。

例如,在cdecl調用約定在C中是這樣工作的:

int callee(int, int, int); 

int caller(void) 
{ 
    int ret; 
    ret = callee(1, 2, 3); 
    ret += 5; 
    return ret; 
} 

翻譯爲:

caller: 
    push ebp  ; store previous stack frame 
    mov  ebp, esp ; set current stack frame (could be used to access local variables and arguments) 
    push 3  ; push arguments to stack from right to left 
    push 2 
    push 1 
    call callee ; eax contains return value of callee after this line 
    add  esp, 12 ; clean stack from arguments passed to callee 
    add  eax, 5 ; add 5 return value of callee 
    pop  ebp  ; restore previous stack frame 
    ret    ; return value in eax 

維基百科大約有不同的調用約定(http://en.wikipedia.org/wiki/X86_calling_conventions)大文章。

相關問題