gpt4 book ai didi

linux - 了解 NASM 程序集中的递归阶乘函数

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:55:51 25 4
gpt4 key购买 nike

在 32 位 Ubuntu 上学习 NASM 程序集。我现在正在尝试学习递归函数,从阶乘开始(注意:这里我假设参数总是非负的)。

假设我有

push 3
call factorial

我想以 6 结尾在EAX .

这是我的尝试:

SECTION .text
global main
main:
; -----------------------------------------------------------
; Main
; -----------------------------------------------------------
push 3
call factorial

; -----------------------------------------------------------
; Exit
; -----------------------------------------------------------
mov EAX,1
int 0x80

; -----------------------------------------------------------
; Recursive Factorial: n! = n * (n - 1)!
; -----------------------------------------------------------
factorial:

push EBP ; Retrieve parameter and put it
mov EBP,ESP ; into EBX register
add EBP,8 ;
mov EBX,[EBP] ; EBX = Param

cmp EBX,0 ; Check for base case
je base ; It is base if (n == 0)

dec EBX ; Decrement EBX to put it in the stack
push EBX ; Put (EBX - 1) in stack
inc EBX ; Restore EBX
call factorial ; Calculate factorial for (EBX - 1)
mul EBX ; EAX = (EAX * EBX) = (EBX - 1)! * EBX
pop EBX ; Retrieve EBX from the stack

jmp end
base: ; Base case
mov EAX,1 ; The result would be 1

end:

pop EBP ; Release EBP
ret

至少它适用于基本情况,哈...但是对于我输入的任何其他值,它总是返回 0 .我怀疑可能是因为 EAX0 , MUL总是会导致 0 ,对此进行解释。为了测试,我决定给出 EAX 2 的值,期待一些非零值,但它一直导致 0 .

你能建议我如何做一个从堆栈中获取参数的递归阶乘函数吗?我相信已经看过一些示例,但是它们要么不是递归的,要么从其他地方获取参数,或者使用了一堆变量(当我认为只用寄存器就可以完成时)。

最佳答案

请注意,factorial(n-1) 将首先覆盖 EBXfactorial(n) 值,因此在 push 之后呈现 inc EBX 毫无意义。达到基本情况后,当您执行 mul 时,您会遇到 EBX 为 0 的情况,当然还有任何 * 0 == 0。

最简单的解决方法是将序言更改为:

push    EBP         ; Retrieve parameter and put it
push EBX ; save previous param
mov EBP,ESP ; into EBX register
add EBP,12 ;
mov EBX,[EBP] ; EBX = Param

以及结语:

pop     EBX         ; restore previous param
pop EBP ; Release EBP
ret

关于linux - 了解 NASM 程序集中的递归阶乘函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19217960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com