堆栈会在需要时分配更多空间还是会溢出? [英] Does a stack allocate more space if needed or does it overflow?

查看:121
本文介绍了堆栈会在需要时分配更多空间还是会溢出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于x86汇编,假设我们有一个像这样的堆栈

For x86 assembly, let's say we have a stack like so

堆栈为它拥有的2个局部变量分配了2个字.但是,如果您强行将第三个局部变量推入堆栈,该怎么办? ESP会向上移动以为变量留出空间吗?还是变量会覆盖ESP?

The stack has 2 words allocated for the 2 local variables it has. But what if you forcibly push a third local variable to the stack. Does the ESP move upwards to make room for the variable or does the variable override the ESP?

推荐答案

对于x86,将数据推送"到堆栈的指令还会修改堆栈指针(在本例中为%esp),以标记新的堆栈顶部.指令弹出"数据会沿相反方向修改堆栈指针.

With x86, instructions that "push" data to the stack also modify the stack pointer (%esp in this case) to mark the new top of stack. Instructions that "pop" data modify the stack pointer in the opposite direction.

在没有特殊推入和弹出指令的计算机上,程序必须首先修改堆栈指针,然后将数据存储到堆栈中.

On machines without special push and pop instructions, the program must first modify the stack pointer and then store data to the stack.

通常,为堆栈保留一个较大的区域.堆栈指针仅标记当前正在使用的部分.程序可以根据需要随意上下移动堆栈指针.

Generally, a large area is reserved for the stack. The stack pointer merely marks the portion that is currently in use. A program is free to move the stack pointer up and down as it needs to.

为堆栈保留的区域可能取决于操作系统和/或开发人员工具.例如,在具有Apple开发人员工具的macOS上,默认堆栈大小为8 MB,可以通过将"-stack_size size "切换到链接器(ld命令)进行更改. (这是针对主堆栈的.使用多个线程的程序为每个创建的线程都有一个额外的堆栈.这些线程的堆栈大小是分别设置的.)

The area reserved for the stack may depend on the operating system and/or the developer tools. For example, on macOS with Apple’s developer tools, the default stack size is eight mebibytes and may be changed with the "-stack_size size" switch to the linker (the ld command). (This is for the main stack. A program that uses multiple threads has an additional stack for each created thread. The stack size for these is set separately.)

尽管为堆栈保留了大范围的虚拟地址空间,但程序启动后,操作系统可能不会将其全部映射到物理内存.操作系统可能只映射一部分,然后随着堆栈增长到该区域映射更多的部分.

Although a large area of virtual address space is reserved for the stack, an operating system might not map it all to physical memory as soon as a program starts. An operating system might map just a portion of it and then map more portions as the stack grows into the area.

通常,超出堆栈的虚拟地址空间的某些部分保持未映射状态,因此尝试访问它会导致异常.该区域中的地址空间页面称为保护页面.因此,如果程序使堆栈超出保留区域并尝试将值写入未映射的保护页,则会发生异常,并且系统将报告堆栈溢出.

Typically, some portion of virtual address space beyond the stack is kept unmapped, so that attempts to access it will cause exceptions. The address space pages in this area are called guard pages. Thus, if a program grows the stack beyond the reserved area and tries to write a value to the unmapped guard page, an exception will occur, and the system will report a stack overflow.

什么也不能阻止程序写入为堆栈保留的区域,但要稍微超出堆栈指针.这将是一个错误,但是通常不会被硬件检测到.此外,执行此操作的程序可能会正常运行一段时间.它可以将数据存储到该区域并按预期加载回去.但是,您在过程中还会发生其他通常不知道的事情.例如,信号可能会传递给您的过程.发生这种情况时,系统会中断程序的常规处理,将新数据压入堆栈,并调用信号处理程序例程.当例程返回时,将从堆栈中删除数据,并且程序将恢复正常执行.但是,如果您的程序已将数据存储在堆栈指针之外,则该数据现在消失了,因为它已被信号处理程序的数据覆盖.因此,将数据存储在堆栈指针之外的程序在大多数情况下似乎都可以运行,但是在信号到达错误时刻的极少数情况下会失败.

Nothing prevents a program from writing into the area reserved for the stack but slightly beyond the stack pointer. This would be a bug, but it generally is not detected by hardware. Furthermore, a program that does this may operate normally for a while; it can store data to this area and load it back as expected. However, there are additional things happening in your process that you are normally unaware of. For example, a signal may be delivered to your process. When this happens, the system interrupts regular processing of your program, pushes new data onto the stack, and calls a signal handler routine. When the routine returns, the data is removed from the stack, and your program resumes normal execution. However, if your program had stored data beyond the stack pointer, that data is now gone, since it was overwritten by the data for the signal handler. Thus, a program that stores data beyond the stack pointer may seem to work most of the time but fail on rare circumstances when a signal arrives at the wrong moment.

(在某些系统上,堆栈的安全区域实际上是超出堆栈指针中地址的固定距离,而不是恰好位于该地址处.这个额外的安全空间可以称为红色区域".)

(On some systems, the safe area of stack is actually a fixed distance beyond the address in the stack pointer, instead of exactly at that address. This extra safe space may be called a "red zone.")

这篇关于堆栈会在需要时分配更多空间还是会溢出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆