这东西看不见摸不着,我觉得很难理解。google这么久回答都差不多,那我说说我的理解,通过高手们的指正,可能好理解些。
我想,每台机器有它的机器代码,用C/C++写的程序,要用这个机器上可用的编译器将其编译成该机器能读能运行的代码。编译器生成的二进制文件保存着文
本,数据还有其他信息,包括运行时所需要的内存。C++程序运行时向系统要一些内存由它自己管理使用,然后它在这些内存中构建起了所谓的“栈”,在内存中
建立了一个后进先出的模型,但我不知道具体硬件的实现技术,先忽略。并且这个栈大小固定,在运行准备阶段一次建好,而所谓的“堆”有一定的扩展空间,可以
动态扩充,并且没有后进先出的机制。
这就是我目前的理解,但我到现在都不知到编译器在编译时到底还做了些什么。比如说类似于“编译时做
XX”,(编译时分配内存、确定,即RTTI之类的)。我就想不通了,它编译它的,程序没编译出来运都没运行,分配个什么内存啊!难道一个运行时大致要消
耗200MB RAM 的程序在编译时也要消耗200MB么?
求高手指教,感激不尽。
一种只能在一端进行插入和删除操作的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。
栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。
栈可以用来在函数调用的时候存储断点,做递归时要用到栈!
以上定义是在经典计算机科学中的解释。
在计算机系统中,栈则是一个具有以上属性的动态内存区域。程序可以将数据压入栈中,也可以将数据从栈顶弹出。在i386机器中,栈顶由称为esp的寄存器进行定位。压栈的操作使得栈顶的地址减小,弹出的操作使得栈顶的地址增大。
栈在程序的运行中有着举足轻重的作用。最重要的是栈保存了一个函数调用时所需要的维护信息,这常常称之为堆栈帧或者活动记录。堆栈帧一般包含如下几方面的信息:
1. 函数的返回地址和参数
2. 临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量。
大致明白了,C/C++都学了,Linux系统学了部分,linux用的就是虚拟内存,那么编译器在编译阶段做了写什么呢?如果只是所谓编译原理里面的您可以不用费力的说了,我才上完第一学期,很多都自学,这个以后会学。还有,我认为“加载器”其实就是相当于Linux Kernel 把一段程序代码载入内存,是有系统某个部分实现的。最后,也就是“栈”除了规定了一段地址外就没有什么物理模型了?还有pop和push是汇编指令还是windows的系统调用呢?
追答第一个问题,比如你int a 然后使用了a这个变量,其实在二进制代码里不会有a b c 这种变量名称,有的只是地址,编译器就是做了这些转化,但是并不是变成了二进制代码,他会把一些用到的函数,变量以一个他知道的形式记下来,然后链接的时候才会知道具体函数代码是什么,最后才成为二进制代码,
pop push 是一个汇编指令,不过是pop push 这个名称是软件逻辑上给的,比如源代码编程了汇编代码然后汇编代码变成了二进制代码,汇编代码里有 pop 那么这个pop 一定被翻译成一定的二进制代码,比如 pop 对应 0x12 push 对应0x23 最终这个值肯定是不会变的。