0
点赞
收藏
分享

微信扫一扫

一次探索栈帧结构的小实验

小黑Neo 2023-03-05 阅读 68

一、引言

C语言中函数调用返回是一种很常见的形式,比如main函数调用了函数A,函数A又调用了函数B。那么函数调用过程中发生了什么,调用结束又是怎么返回到正确位置的。最近读了一些相关的资料,但书上得来终觉浅,今天就动手验证下书上的小例子,并写个博客记录下这个过程。

二、理论知识

1、进程的虚拟地址空间

有一道很经典的面试题,是问程序中各元素在内存中的分布。比如全局变量(已初始化、未初始化)、局部变量、静态变量等,在进程地址空间的什么段?或者直接问程序BSS段/栈空间/堆空间是什么,保存什么内容等。没有接触过这一块的肯定是一脸懵圈。 进程地址空间分布.jpg

2、栈帧结构

栈的增长方向是从高地址到低地址的。函数调用时,会按照下图所示的方式保存栈帧信息。 栈帧结构.jpg

三、实验过程

实验小程序源自参考文献1,本文在自己的Linux系统上做了验证。

测试环境:Ubuntu 18.04

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

#define MAX     (1UL << 29)

typedef unsigned long long u64;
typedef unsigned int u32;

u32 max_addend = MAX;

u64 sum_till_max(u32 n)
{
	u64 sum;
	n++;
	sum = n;

	if (n < max_addend)
		sum += sum_till_max(n);
		
	return sum;
}

int main(int argc, char** argv)
{
	u64 sum = 0;

	if((argc ==2) && (isdigit(*argv[1])))
		max_addend = strtoul(argv[1], NULL,0);

	if (max_addend >MAX || max_addend == 0) 
	{
		fprintf(stderr, "Invalid number is specified\n");
		return 1;
	}

	sum = sum_till_max(0);
	printf("sum(0..%u) = %llu\n", max_addend, sum);
	
	return 0;
}

四、参考文献

1、Debug Hacks中文版 -- 深入调试的技术和工具,电子工业出版社 2、文中图片来自网络,详细出处未知

举报

相关推荐

0 条评论