这是在堆栈上传递变量的正确方法吗?
我编写了一个简单的程序,它将预定义的数字取预定义的幂并返回结果。它位于 Linux 的 NASM 汇编中。我一直在尝试了解如何使用堆栈将变量传递给函数,并想确保我正确地做到了这一点。它返回正确的数字,但我不知道它是否正确:
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
任何建议将不胜感激!
I wrote a simple program which takes a predefined number to a predefined power and returns the result. It's in NASM assembly, for Linux. I've been trying to get my head around how to use the stack to pass variables to functions, and wanted to make sure I did this correctly. It returns the correct number, but I have no idea if it's correct:
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
Any advice would be much appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
大部分看起来都不错。但是,在电源恢复后,您应该从堆栈中删除变量。在这些情况下这并不重要,因为 _start 不会返回,但如果您尝试从返回且不清理的函数调用函数,则会很重要。函数的返回地址存储在堆栈中并由 ret 指令弹出,因此如果堆栈顶部有其他内容,您将返回到错误的位置。
如果您编写一个调用许多其他函数的函数,最好在函数开头为堆栈参数分配空间,在每次函数调用之前写入它,并在函数末尾将其从堆栈中删除。这样,您就可以减少推送和弹出的时间,因为您可以使用带有正确地址的
mov
来代替。作为对你的幂函数的评论:它目前仅在幂至少为 2 时才起作用。您可以通过以下方式将最小幂更改为 0:
示例:
It looks good for the most part. However, after the power returns, you should remove the variables from the stack. It doesn't matter in these circumstances since _start doesn't return, but it will matter if you try to call a function from a function that returns and doesn't clean up. The return address of a function is stored on the stack and popped off by the
ret
instruction, so if you have something else on the top of the stack you will return to the wrong location.If you write a function that calls a lot of other functions, it is better to allocate space for stack arguments at the beginning of the function, write to it before each function call, and remove it from the stack at the end of the function. That way, you spend less time pushing and popping because you can use
mov
with the proper address instead.As a comment on your power function: It currently only works if the power is at least 2. You could change the minimum power to 0 by:
Example: