栈(stack)简单实现,系统栈是如何保存函数调用信息的?

系统栈和栈

自己实现个栈很简单,但是用栈的思想在有时候比较抽象,尤其是在使用系统栈的时候(递归)。栈的主要特点就像是你放很多大木板子在你的收纳盒里,模板放入后,每次只能取走最后放入的模板,是“先入后出”,或者“后入先出”。

稍微谈一下递归:本质上来讲能用数学归纳法证明的数学问题都可以用递归解决,用栈能解决的问题也都能递归解决(废话都是栈)。递归的核心思想在于:在这一阶段,只考虑目前这一小阶段的情况,以及和前/后阶段的联系,随后考虑一个最基础的跳出条件。感觉放这里不太合适,还是以后专门说一说递归吧。

系统栈如何保存函数调用信息

所谓系统栈,其实也是和栈比较类似的一种东西,可以用ollydbg或者x32/x64dbg去看一个简单的C语言程序是怎么被压栈的。或者也可以使用VS2019ALT 8反汇编查看

大概情况如下:
比如有一个C语言程序求阶乘,

那么汇编大概就是:

.586
.model flat,stdcall
.stack 4096

includelib libcmt.lib
includelib legacy_stdio_definitions.lib ;stdio.h
includelib libvcruntime.lib
includelib libucrt.lib

extern printf:NEAR
extern scanf:NEAR
ExitProcess PROTO, dwExitCode:DWORD

.data
	msg BYTE "%d! = %d", 0Ah, 0
	result BYTE "The result is %d", 0Ah, 0
	printfact BYTE "%d! = %d",0Ah,0
	prompt BYTE "Enter an integer: ",0Ah,0
	num dd 0
	scan BYTE "%d",0
.code

fact:
	push ebp
	mov ebp, esp
	mov ecx, [ebp+8]  ; ecx = n
	;mov eax, 1        ; accumulator eax = ecx*fact(ecx-1)
	cmp ecx, 1
	jle base

	push ecx 
	sub ecx, 1
	push ecx
	call fact
	add esp, 4
	pop ecx
	mul ecx ;eax = ecx*fact(ecx-1)
	push eax
	push ecx

	
	push eax
	push ecx
	push offset msg
	call printf
	add esp,12

	pop ecx
	pop eax


	pop ebp
	ret


base:  ; return 1
	mov eax, 1
	pop ebp
	ret

	
main PROC c
	
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值