gpt4 book ai didi

assembly - 未处理的异常 : Recursive Factorial in assembly (MASM)

转载 作者:行者123 更新时间:2023-12-02 00:14:54 25 4
gpt4 key购买 nike

我用汇编语言 (MASM) 编写了一个程序,让学生练习计算组合。该程序递归地计算阶乘。我使用一个称为组合的过程,它接收 n 和 r,然后得到 (n=r)!、n! 和 r!通过调用称为阶乘的过程。阶乘是递归的。

.data
n DWORD ?
r DWORD ?
result DWORD ?
answer DWORD ?
divisor DWORD ?

.code
MAIN PROC

(一些初步的程序调用)

push OFFSET divisor     ;ebp+20
push n ;ebp+16
push r ;ebp+12
push OFFSET result ;ebp+8
call combinations

;*************************************************
; combinations calls factorial (3 times) to calculate n!, r!, and (n-r)!.
; combinations calculates n!/(r!(n-r)!) , and stores the value in result.
; receives: accepts n and r by value and result by address.
; returns: none
; preconditions: none
; registers changed: eax, ebx, edx
;*************************************************
combinations PROC
push ebp
mov ebp,esp

mov eax, [ebp+16] ;find (n-r)!
sub eax, [ebp+12]
mov ebx, eax
push ebx
call factorial
pop ebx
mov edx,[ebp+20] ;move (n-r)! into result
mov [edx],eax

mov ebx, [ebp+12] ;find r!
push ebx
call factorial
pop ebx

mov edx,[ebp+20]
mov ebx, [edx]
mul ebx ;r!*(n-r)!, store product in eax
mov ebx, [ebp+20]
mov [ebx], eax ;store product in divisor variable

mov ebx, [ebp+16] ;find n!
push ebx
call factorial
pop ebx
mov edx,[ebp+20]
mov ebx,[edx] ;move value of divisor into ebx

mov edx, 0
div ebx ;divide n! by divisor (r!*(n-r)!)
mov ebx, [ebp+8]
mov [ebx],eax ;move quotient into result

pop ebp
ret 16
combinations ENDP

;*************************************************
; calculates factorial recursively
; receives:
; returns: factorial solution in eax
; preconditions: none
; registers changed: eax
;*************************************************
factorial PROC
mov eax,dword ptr [esp+4]
cmp eax,1
jle endRecursive
dec eax
push eax
call factorial
mov esi,dword ptr [esp+4]
mul esi
endRecursive:
ret 4
factorial ENDP

一切都按预期进行,我得到了所需的值。然而,当所有的计算都完成并且程序在组合过程结束时到达语句“ret 16”时,我得到以下异常:

Project.exe 中 0x76f915de 处的未处理异常:0xC0000005:访问冲突。

我已经通过调试器运行它,并尝试在我计算错误的情况下更改返回语句,但到目前为止我所做的一切都没有奏效。也许这是盯着这个太久的情况,但任何想法都会受到赞赏。提前致谢。

更新: 仅在调试器中跟踪 ebp 和 esp:看起来当程序从最后一次阶乘调用中出来时,esp 是 ebp 的 +12,因此每次调用都会增加 +4阶乘。结果,当程序命中 pop ebp 时,ebp 指向 r 而不是它应该指向的位置。有关如何解决此问题的任何建议?

最佳答案

您需要删除在对 factorial 的三个顶级调用之后出现的三个 pop ebx 指令。由于 factorial 已经将其参数从堆栈中弹出(通过使用 ret 4),尝试通过执行 pop ebx 操作再次删除参数向上堆栈指针。

关于assembly - 未处理的异常 : Recursive Factorial in assembly (MASM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13657007/

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