日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

调用栈(call stack)

發布時間:2024/8/1 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 调用栈(call stack) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

調用棧的英文叫做call stack,從其英文書名來看,知道它本身就是一個棧,故而它滿足棧的先入后出的特性。

wiki上有篇文章講述call stack:http://en.wikipedia.org/wiki/Call_stack

關于棧的溢出(stack overflow),有下面的定義:

Since the call stack is organized as a?stack, the caller?pushes?the return address onto the stack, and the called subroutine, when it finishes,?pops?the return address off the call stack and transfers control to that address. If a called subroutine calls on to yet another subroutine, it will push another return address onto the call stack, and so on, with the information stacking up and unstacking as the program dictates. If the pushing consumes all of the space allocated for the call stack, an error called a?stack overflow?occurs, generally causing the program to?crash.

關于call stack的作用,它也談到了:

Storing the return address?When a subroutine is called, the location (address) of the instruction at which it can later resume needs to be saved somewhere. Using a stack to save the return address has important advantages over alternatives. One is that each task has its own stack, and thus the subroutine can be?reentrant, that is, can be active simultaneously for different tasks doing different things. Another benefit is that?recursion?is automatically supported. When a function calls itself recursively, a return address needs to be stored for each activation of the function so that it can later be used to return from the function activation. This capability is automatic with a stack.

存儲指令的返回地址,是call stack最重要的作用,簡單,而且會帶來很多其它的好處,譬如每個線程維護自己的調用棧,還有遞歸調用。

Local data storage?A subroutine frequently needs memory space for storing the values of?local variables, the variables that are known only within the active subroutine and do not retain values after it returns. It is often convenient to allocate space for this use by simply moving the top of the stack by enough to provide the space. This is very fast compared to?heap?allocation. Note that each separate activation of a subroutine gets its own separate space in the stack for locals.

局部數據存儲在棧這樣的存儲空間中,比堆存儲要快得多,原因在于,只需要簡單的移動棧頂的位置就可以了,當需要分配棧空間時。

Parameter passing?Subroutines often require that values for?parameters?be supplied to them by the code which calls them, and it is not uncommon that space for these parameters may be laid out in the call stack. Generally if there are only a few small parameters,?processor registers?will be used to pass the values, but if there are more parameters than can be handled this way, memory space will be needed. The call stack works well as a place for these parameters, especially since each call to a subroutine, which will have differing values for parameters, will be given separate space on the call stack for those values.

調用棧還可以用來傳遞調用函數的參數,通常是在參數較多的時候。

Pointer to current instance?Some?object-oriented languages?(e.g.,?C++), store the?this?pointer?along with function arguments in the call stack when invoking methods. The?this?pointer points to the?object?instance?associated with the method to be invoked.

它還可以用來傳遞C++中的this指針。

Enclosing subroutine context?Some programming languages (e.g.,?Pascal?and?Ada) support?nested subroutines, allowing an inner routine to access the context of its outer enclosing routine, i.e., the parameters and local variables within the scope of the outer routine. Such static nesting can repeat - a function declared within a function declared within a function... The implementation must provide a means by which a called function at any given static nesting level can reference the enclosing frame at each enclosing nesting level. Commonly this reference is implemented by a pointer to the encompassing frame, called a "downstack link" or "static link", to distinguish it from the "dynamic link" that refers to the immediate caller (which need not be the static parent function). For example, languages often allow inner routines to call themselves recursively, resulting in multiple call frames for the inner routine's invocations, all of whose static links point to the same outer routine context. Instead of a static link, the references to the enclosing static frames may be collected into an array of pointers known as adisplay?which is indexed to locate a desired frame. The?Burroughs B6500?had such a display in hardware that supported up to 32 levels of static nesting.

用來解決一些語言支持的閉包特性。

處理以上的作用外,文章還談到了其它一些作用。

?

關于call stack的具體結構布局,不同的平臺系統有不同的實現:

一個call stack通常由一個或多個棧幀(stack frames)組成,假如一個函數DrawLine正在被另外一個函數DrawSquare調用,這時候的call stack可以表示如下:

? ? ? ? ? ? ? ? ? ?

這里棧頂向上(高地址)增長,不同的硬件平臺有不同的實現。

The stack frame at the top of the stack is for the currently executing routine. The stack frame usually includes at least the following items (in push order):

  • the arguments (parameter values) passed to the routine (if any);
  • the return address back to the routine's caller (e.g. in the?DrawLine?stack frame, an address into?DrawSquare's code); and
  • space for the local variables of the routine (if any).

The stack and frame pointers

The data stored in the stack frame may sometimes be accessed directly via the?stack pointer?register (SP, which indicates the current top of the stack). However, as the stack pointer is variable during the activation of the routine, memory locations within the stack frame are more typically accessed via a separate register which makes relative addressing simpler and also enables dynamic allocation mechanisms (see below). This register is often termed the?frame pointer?or?stack base pointer?(BP) and is set up at procedure entry to point to a?fixed?location in the frame structure (such as the return address).

Stack frame sizes

As different routines have different parameters and local data, stack frames have varying sizes. Although they may often be fixed across all activations of a particular routine, many modern languages also support?dynamicallocations on the stack, which means that the local data area will vary from activation to activation with a size that may be unspecified when the program is?compiled. In this case, access via a frame pointer, rather than via the stack pointer, is usually necessary since the offsets from the stack top to values such as the return address would not be known at compile time. If the subroutine does not use dynamic stack allocation and does not call any further subroutines, the frame pointer is not needed, and the register may be used for other purposes.

Storing the address to the caller's frame

In most systems a stack frame has a field to contain the previous value of the frame pointer register, the value it had while the caller was executing. For example, the stack frame of?DrawLine?would have a memory location holding the frame pointer value that?DrawSquare?uses (not shown in the diagram above). The value is saved upon entry to the subroutine and restored upon return. Having such a field in a known location in the stack frame enables code to access each frame successively underneath the currently executing routine's frame, and also allows the routine to easily restore the frame pointer to the caller's frame, just before it returns.

Lexically nested routines

Further information:?Nested function?and?Non-local variable

Programming languages that support?nested subroutines?also have a field in the call frame that points to the stack frame of the?latest?activation of the procedure that most closely encapsulates the callee, i.e. the immediatescope?of the callee. This is called an?access link?or?static link?(as it keeps track of static nesting during dynamic and recursive calls) and provides the routine (as well as any other routines it may invoke) access to the local data of its encapsulating routines at every nesting level. Some architectures, compilers, or optimization cases store one link for each enclosing level (not just the immediately enclosing), so that deeply nested routines that access shallow data do not have to traverse several links; this strategy is often called a?display.[1]?Access link(s) can be optimized away in cases where an inner function does not access any (non constant) local data in the encapsulation—pure functions, i.e. routines communicating via argument(s) and return value(s) only would be an example of this. Some historical computers, such as the?Burroughs large systems, had special "display registers" to support nested functions while compilers for most modern machines (such as the ubiquitous x86) simply reserve a few words on the stack for the pointers, as needed.

Overlap

For some purposes, the stack frame of a subroutine and that of its caller can be considered to overlap, the overlap consisting of the area where the parameters are passed from the caller to the callee. In some environments, the caller pushes each argument onto the stack, thus extending its stack frame, then invokes the callee. In other environments, the caller has a preallocated area at the top of its stack frame to hold the arguments it supplies to other subroutines it calls. This area is sometimes termed the?outgoing arguments area?or?callout area. Under this approach, the size of the area is calculated by the compiler to be the largest needed by any called subroutine.

?

?

轉載于:https://www.cnblogs.com/zerolee/archive/2012/06/17/2552760.html

總結

以上是生活随笔為你收集整理的调用栈(call stack)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。