2011-04-06 94 views
0

我寫了一個簡單的程序,它將一個預定義的數字轉換爲預定義的權力並返回結果。它在NASM彙編中,用於Linux。我一直試圖讓我的頭在如何使用堆棧來傳遞函數的變量,並希望確保我做到了這一點。它返回正確的數字,但我不知道它是否正確:這是將變量傳遞給堆棧的正確方法嗎?

section .text 
    global _start 

_start: 
    push dword 3  ;(power) 
    push dword 2  ;(num) 

    call power 

    mov ebx, eax 
    mov eax, 1 
    int 0x80 

power: 
    push ebp 
    mov ebp, esp 
    sub esp, 8  ;reserve space for two local vars 
    push dword [ebp+8] 
    pop dword [ebp-4] ;store original num as a local var 
    push dword [ebp+12] 
    pop dword [ebp-8] ;store power in a local counter var 
    dec dword [ebp-8] 
    mov eax, [ebp-4] ;store original num in eax (current val)  
    jmp power_loop 

power_loop: 
    imul eax, dword [ebp-4] ;multiply current val by original num 
    dec dword [ebp-8] ;decrement counter 

    cmp dword [ebp-8], 0 
    jne power_loop 

    mov esp, ebp  ;restore stack pointer 
    pop ebp 
    ret 

任何意見將不勝感激!

+1

如果我不准問,什麼是寫彙編語言,看起來儘可能像它出來一個C編譯器的點(其優化關閉,在那個)?使用寄存器! – 2011-04-06 03:18:05

+0

我知道我本來可以使用寄存器,但我想學會裝配以獲得樂趣 - 這只是一個練習,學習如何使用堆棧傳遞參數。 – user693861 2011-04-07 04:16:06

+0

使用堆棧傳遞參數是有些可以接受的(當與C代碼等接口時是必需的),但在完全不必要的情況下在堆棧上創建局部變量是一個完全不同的故事(無論如何)。 – 2011-04-07 04:18:16

回答

1

大部分看起來不錯。但是,在電源恢復後,您應該從堆棧中移除變量。在這些情況下並不重要,因爲_start不會返回,但如果您嘗試從返回並且不清除的函數中調用函數,那麼這很重要。函數的返回地址存儲在堆棧中,並由ret指令彈出,所以如果堆棧頂部有其他東西,則會返回到錯誤的位置。

_start: 
    push dword 3 
    push dword 2 
    call power 
    add esp,8 ; Removes two dwords from stack 

如果你編寫調用了很多其他功能的功能,最好是在函數的開始分配堆棧變量空間,每個函數調用之前寫它,並從堆棧中刪除在函數結束時。這樣,您花更少的時間推送和彈出,因爲您可以使用mov而不是正確的地址。

_start: 
    sub esp,8 ; Make room for two dwords 
    mov dword [esp+4], 3 
    mov dword [esp], 2 
    call power 
    add esp,8 ; Removes two dwords from stack 

隨着你的冪函數評論:

  • 開始EAX在1
  • :它目前只能如果功率至少2.您可以通過改變最小功率爲0在循環之前,不要遞減計數器變量
  • 檢查是否計數器在循環的開始是0

例:

; dec dword [ebp-8] ; Don't do this 
    mov eax, dword 1 
    jmp power_loop 

power_loop: 
    cmp dword [ebp-8], 0 
    je end_loop 

    imul eax, dword [ebp-4] ;multiply current val by original num 
    dec dword [ebp-8] ;decrement counter 
    jmp power_loop 

end_loop: 
    mov esp, ebp 
+0

太棒了,非常感謝您的詳細回覆!這東西終於開始有意義了:) – user693861 2011-04-07 04:14:28