gpt4 book ai didi

assembly - 递归过程

转载 作者:行者123 更新时间:2023-11-30 03:27:34 25 4
gpt4 key购买 nike

我应该编写递归程序来计算给定范围内可被 3 整除的数字之和。首先,从键盘读取两位数 N,这给了我们 1 到 N 的范围。 N 号通过堆栈传递给过程。此外,范围内数字的总和应通过堆栈返回。问题是,我无法设法通过堆栈返回总和。所以,一点点帮助不会有坏处。这是代码:

data segment
n dw ?
sum dw ?
ends

stack segment
dw 128 dup(0)
ends

code segment
start:
mov ax,@data
mov ds,ax
mov es,ax

mov cx,3

mov ah,1
int 21h
sub al,30h
mov ah,0
mov bx,10d
mul bx

mov n,ax

mov ah,1
int 21h
sub al,30h
mov ah,0
add n,ax

mov ax,n

push ax

call suma

mov ax, 4c00h
int 21h

suma proc
push bp
mov bp,sp

mov ax,[bp+4]
cmp ax,1
je l1

dec ax
push ax

call suma

mov ax,[bp+4]
push ax
div cl
cmp ah,0
pop ax
JNE l1

add sum,ax

L1:
pop bp
ret 2

suma endp

ends

end start

最佳答案

正如 Jester 所指出的,这是一项愚蠢的任务,但如果您很好地理解堆栈,您应该能够以任何方式解决它。

您当前的代码:

; For example let's say sp = 54  (address 54 in memory)
push ax ; store argument n, sp = 52
call suma ; do the call
; inside suma under the argument there are pushed also
; return address by CALL, sp =50
; and old bp by PUSH bp, sp = 48
; then [sp+4] points to argument n (48+4 = 52)
; stack is restored by the function ("ret 2"), sp = 54

现在如果你想把结果放在栈上,你必须从调用者的角度保留栈空间,因为在suma之后。返回,sp在我的示例中恢复为“54”,以及从 suma 写入堆栈的所有内容拜访下级sp地址可能已经被覆盖(例如,如果中断发生在 ret 2 和您的下一条指令之间,那么中断确实使用了地址 54 以下的堆栈内存,并覆盖了它)。在地址 54+ 处写入内存的任何内容都会对调用者有效,但会破坏调用者存储在那里的值。

顺便说一句,您当前的相关代码不会在 ax 中返回结果,因为它在以错误的方式进行递归时会自行覆盖它,并在地址 sum 的内存中累积结果, 未由 suma 初始化, 所以它只会工作一次。可以这样写,即使多次调用,递归也会返回正确的总和(首先将总和归零,然后调用 F(n-1) 并根据需要在 F(n- 1)).


因此,要么决定返回该值代替参数 n,那么您必须:

  • 内部suma将结果存储到 [ebp+4]内存
  • 返回 ret (不从栈中释放参数)
  • call suma之后无处不在pop ax从堆栈中选择结果

或者在参数之上保留栈空间,比如:

sub  sp,2 ; make space for result in stack
; you can also use another bogus "push ax", not caring about value, just adjusting sp
push ax ; push argument n
call suma
pop ax ; read result + restore stack

然后里面suma你必须将结果存储到 [bp+6] , ret 2保持原样,只释放参数。


无论哪种方式,调用者都必须保留堆栈空间,因为任何未保留的堆栈空间(低于 sp 的当前值)都可能随时被中断处理程序覆盖(在 x86 16b 实模式中)。

关于assembly - 递归过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47249697/

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