2011-04-06 97 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