我试图了解如何构建堆栈框架以及哪些变量(参数)以什么顺序被压入堆栈?一些搜索结果表明,C / C ++编译器根据函数内执行的操作进行决策。例如,如果假定该函数只是将传入的int值加1(类似于++运算符)并返回它,则它将把该函数的所有参数和局部变量放入寄存器中。
我想知道哪些寄存器用于返回或按值传递参数。引用如何返回?编译器如何在eax,ebx,ecx和edx之间进行选择?
我需要了解什么才能了解函数调用期间如何使用,构建和销毁寄存器,堆栈和堆引用?
我试图了解如何构建堆栈框架以及哪些变量(参数)以什么顺序被压入堆栈?一些搜索结果表明,C / C ++编译器根据函数内执行的操作进行决策。例如,如果假定该函数只是将传入的int值加1(类似于++运算符)并返回它,则它将把该函数的所有参数和局部变量放入寄存器中。
我想知道哪些寄存器用于返回或按值传递参数。引用如何返回?编译器如何在eax,ebx,ecx和edx之间进行选择?
我需要了解什么才能了解函数调用期间如何使用,构建和销毁寄存器,堆栈和堆引用?
Answers:
除了Dirk所说的以外,堆栈帧的一个重要用途是保存寄存器的先前值,以便可以在函数调用后恢复它们。因此,即使在使用寄存器传递参数,返回值并保存返回地址的处理器上,这些寄存器的值也将在函数调用之前保存在堆栈中,以便可以在调用之后将其恢复。这样一来,一个函数可以调用另一个函数,而无需覆盖其自身的参数或忘记其自身的返回地址。
因此,在典型的“通用”系统上从函数A调用函数B可能涉及以下步骤:
这绝不是函数调用可以工作的唯一方法(我可能会失调一两步),但是它应该使您了解如何使用堆栈来让处理器处理嵌套的函数调用。
push
和pop
是堆栈上的两个基本操作。堆栈是后进先出的结构,就像一books书。当您使用时push
,您将一个新的对象放在堆栈的顶部。当您pop
从堆栈顶部取出一个对象时。不允许在中间插入或删除对象,只能在堆栈的顶部进行操作。您可能会在Wikipedia上阅读更多有关堆栈的信息,尤其是有关程序堆栈的信息。
如果您非常了解堆栈,那么您将了解内存在程序中的工作方式,如果您了解内存在程序中的工作方式,则将了解函数在程序中的存储方式,如果您了解函数在程序中的存储方式,则将了解递归函数的工作方式以及是否您了解递归函数的工作原理,您将了解编译器的工作原理,如果您了解编译器的工作原理,您的想法将像编译器一样工作,并且您将很容易调试任何程序
让我解释一下堆栈是如何工作的:
首先,您必须知道函数如何存储在堆栈中:
堆存储动态内存分配值。堆栈存储自动分配和删除值。
让我们用例子来理解:
def hello(x):
if x==1:
return "op"
else:
u=1
e=12
s=hello(x-1)
e+=1
print(s)
print(x)
u+=1
return e
hello(4)
现在了解该程序的各个部分:
现在让我们看看什么是堆栈以及什么是堆栈部分:
堆栈分配:
记住一件事,无论任何函数加载了他的所有本地变量,或者任何将立即从堆栈返回的东西都将返回其堆栈框架,该函数都会“返回”。这意味着当任何递归函数获得基本条件并且我们在基本条件之后放置return时,这样基本条件将不会等待加载位于程序“ else”部分中的局部变量,它将立即从堆栈中返回当前帧,现在如果返回一帧返回下一帧在激活记录中。实际看到这一点:
块的解除分配:
因此,现在无论何时找到返回语句的函数,它都会从堆栈中删除当前帧。
从堆栈返回时,值将以它们在堆栈中分配的顺序相反的顺序返回。
这些描述非常简短,如果您想更深入地了解堆栈和双递归,请阅读此博客的两篇文章: