问题
程序是怎样被机器所读懂的?
指令在CPU里面是怎样执行的?
为什么有时候会出现stack overflow报错?
怎么避免呢?
计算机指令
CPU硬件上是一个超大规模的集成电路,软件上是一个执行计算机指令的逻辑机器。
计算机指令=机器语言:CPU能听懂的语言。
计算机指令集:数学意义上的集合,计算机指令的集合,不同架构的CPU的指令集也不一样。
计算机程序指令有成千上万条,不可能一直放在CPU中,在程序不运行的情况下,计算机程序是存储在存储器中的,执行的时候在读取到CPU中执行,这类型的计算机叫做存储程序型计算机。
编译:将一个程序翻译成一个汇编代码的过程。
汇编:汇编代码通过汇编器翻译成机器码的过程。
指令类型
指令跳转
指令是一条一条顺序执行的。
CPU由一堆寄存器组成。
寄存器:CPU内部有多个触发器或锁存器组成的简单电路
程序执行:CPU读取PC寄存器里地址的指令到指令寄存器,然后指令长度自增,按顺序读取下一条指令。
J类指令如(jump)也就是跳转指令,会修改PC寄存器里面的地址,指令就不会按顺序加载,if..else/while/for就是这么实现跳转的。
函数调用发生stack overflow
函数调用的时候会进行压栈、出栈等操作。
程序栈存在大小限制,所以无限递归、递归层数过深、在栈空间内创建非常占内存都有可能带来stack overflow报错。
函数内联优化,可以减少CPU的指令数,地址跳转也不需要,也不用进行压栈出栈操作。但是程序指令在多个地方被调用会展开多次,使得整个程序的占用空间变大。
函数调用栈
栈区(stack): 高地址向低地址生长的一块连续的内存区域,所以栈顶地址和栈的最大容量都是系统预先规定好的。
栈帧(stack frame):函数调用经常是嵌套的,在同一时刻,堆栈中会有多个函数的信息,每个未完成运行的函数占用一个独立连续区域(包含这个函数涉及的参数,局部变量,返回地址等相关信息),称为栈帧。
寄存器(register):
rbp
(register base pointer)栈基地址寄存器,保存当前帧的栈底地址。
rsp
(register stack pointer)栈指针寄存器,保存当前栈顶地址。
push
压栈。
pop
出栈。
领取专属 10元无门槛券
私享最新 技术干货