程序中的抽象类

时间:2017-11-12 14:00:40

标签: c++

我应该写一个形状为

的c ++程序

1 个答案:

答案 0 :(得分:2)

正如杰斯特所指出的,这是一项愚蠢的任务,但如果你理解堆栈的话,你应该能够以任何方式解决它。

您当前的代码确实:

; 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将恢复为&#34 ; 54"在我的示例中,从suma调用低sp地址写入堆栈的任何内容都可能已被覆盖(例如,如果在ret 2和下一条指令之间发生中断,则中断执行使用地址54下面的堆栈内存,覆盖它)。在地址54+处写入内存的任何内容都可以在调用者中存活,但会破坏调用者在那里存储的值。

顺便说一下,你当前的代码并没有在ax中返回结果,因为它在以错误的方式进行递归的同时会覆盖它本身,并累积结果存储在地址sum的内存中,未由suma初始化,因此它只能运行一次。有可能以这种方式编写它,递归将返回正确的总和,即使是多次调用(首先将总和归零,然后调用F(n-1)并添加" n" as需要得到那个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实模式下)。