堆栈在微处理器中的作用是什么?

发布于 2024-07-27 04:30:11 字数 22 浏览 8 评论 0原文

堆栈在微处理器中的作用是什么?

What is the role of stack in a microprocessor?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

无边思念无边月 2024-08-03 04:30:11

堆栈主要在函数调用期间使用,但根据语言和编程级别,它可以用于临时存储处理器寄存器数据或其他变量。

此外,当使用将部分数据存储在堆栈中并再次调用自身的递归函数时,堆栈还可以用于短期大规模数据存储。

堆栈的通用用途用于

  1. 返回地址
    • 返回值
    • 被调用函数的参数
    • 被调用函数中的局部变量
    • 将在被调用函数中重用的处理器寄存器

并且,是的,堆栈也可用于漏洞
它的本质是将返回地址携带到被调用函数返回的位置,
再加上 C 语言中数组边界检查的弱点,给出了一个非常
在易受攻击的堆栈中导致缓冲区溢出的好方法(不安全)写)程序。

Stack is used largely during a function call but depending on the language and level of programming it may be used to temporarily store processor register data or other variables.

Further, the stack may also be used for short-term large-scale storage of data when using recursive functions that store partial data in the stack and call themselves again.

The generic use of stack is for,

  1. Return address
    • return value
    • parameters to called function
    • local variables in the called function
    • processor registers that will be reused in the called function

And, yes, stack is also used for exploits.
Its nature of carrying the return-address to where a called function returns back,
coupled with the weakness of array-bounds checks in the C language, gives a very
nice way to cause buffer overflows in the stack of a vulnerable (unsafely written) program.

糖粟与秋泊 2024-08-03 04:30:11

在最底层,堆栈是某些指令存储或检索数据以及发生中断时存储数据的地方。 微处理器各不相同,但有 5 种一般类型的堆栈特定指令:

  1. PUSH - 将数据放入堆栈
  2. POP(或 PULL) - 从堆栈中“删除”数据
  3. CALL - 跳转到子例程并将返回地址放入堆栈
  4. RETURN - 通过将堆栈顶部 INT(或 SWI)加载到程序计数器来从子例程返回
  5. - 软件中断; 专门的 CALL

当处理器中断发生时(由于外部设备),CPU 将在堆栈上保存当前程序计数器和(通常)标志寄存器并跳转到处理子例程。 这允许处理子例程处理中断并返回到 CPU 正在执行的任何操作,并保留其当前状态。

虽然微处理器一次只有一个堆栈处于活动状态,但操作系统可以使其看起来好像有多个堆栈。 至少一个用于操作系统,一个用于每个进程,一个用于每个线程。 事实上,线程本身可以实现多个堆栈。

在更高的层面上,无论使用什么语言来实现线程,通常都会使用堆栈来存储函数调用参数、局部变量和函数调用返回值(这里概括地说——请参阅您的语言的低级版本)具体细节的文档)。

我对堆栈的自下而上的解释就这样结束了。

At the lowest level the stack is the place where certain instructions store or retrieve data and where data is stored when an interrupt occurs. Microprocesors vary, but there are 5 general types of stack-specific instructions:

  1. PUSH - put data onto the stack
  2. POP (or PULL) - "remove" data from the stack
  3. CALL - jump to a subroutine and put the return address on the stack
  4. RETURN - return from a subroutine by loading the program counter with the stack top
  5. INT (or SWI) - software interrupt; a specialized CALL

When a processor interrupt occurs (due to an external device), the CPU will save the current program counter and (usually) the flags register on the stack and jump to the handling subroutine. This allows the handling subroutine to process the interrupt and return to whatever the CPU was doing with its current state preserved.

While a microprocessor has only one stack active at a time, the operating system can make it appear as if there are multiple stacks. At least one for the OS, one for each process and one for each thread. In fact, the threads themselves may implement multiple stacks.

At a higher level, whatever language is used to implement a thread will often use the stack for its own purposes to store functional call parameters, local variables and function call return values (speaking in broad strokes here -- consult your languages' low-level documentation for specific detail).

Thus concludes my bottom-up explanation of the stack.

冷︶言冷语的世界 2024-08-03 04:30:11

在计算的早期,子例程调用是通过每个子例程都有一个内存 RAM 字来处理的,以指示它是从哪里调用的。 要调用子例程,可以执行以下操作:

  load foo_return with #LABEL_123
  goto foo
#LABEL_123:
  ...code to execute after return from foo


foo:
  ... do stuff
  goto foo_return

通过让调用者将返回地址放入寄存器,并让例程将其存储到入口处的“返回”位置,可以优化此模式。 这种模式有效,但有一些问题。 它不仅通常会浪费内存,而且无法处理递归或可重入代码。 添加堆栈可以简化代码,让调用者只需说“将返回地址存储在合适的地方”,而不会干扰任何较早的地址,并且被调用函数只需说“返回到最近没有调用过的调用者”还没有返回”。 这允许开发可重入代码,并且意味着只需要存储足够的返回地址来处理实际发生的最深嵌套的函数调用链。

In the early days of computing, subroutine calls were handled by having a word of memory RAM with each subroutine to indicate where it was called from. To call a subroutine, one would do something like:

  load foo_return with #LABEL_123
  goto foo
#LABEL_123:
  ...code to execute after return from foo


foo:
  ... do stuff
  goto foo_return

This pattern might be optimized by having the caller place the return address into a register, and having the routine store it to the "return" spot on entry. This pattern worked, but it had a few problems. Not only did it generally waste memory--it also had no means of dealing with recursive or re-entrant code. Adding a stack made it possible to simplify the code by having the caller simply say "store the return address someplace suitable", without disturbing any earlier ones, and for the called function to simply say "return to the most recent caller that hasn't been returned to yet". This allowed for the development of re-entrant code, and meant that it was only necessary to store enough return addresses to handle the deepest nested chain of function calls that would ever actually occur.

和影子一齐双人舞 2024-08-03 04:30:11

这取决于微处理器。 一般来说,它的作用是保存局部变量和函数的参数。

实际上它不在微处理器中,而是在中央存储器中。

It depends on the microprocessor. Generally its role is keeping local variables and functions' parameters.

And actually it's not in the microprocessor, it's in the central memory.

弃爱 2024-08-03 04:30:11

堆栈用于在函数调用期间存储和检索返回地址。 它在嵌套函数调用或递归函数调用期间得到很好的利用。 它还用于将参数传递给函数

在微处理器上,它还用于在上下文切换之前存储状态寄存器内容

干杯

Stack is used to store and retrieve return addresses during function calls. Its put to good use during nested function calls or recursive function calls. It is also used to transfer arguments to a function.

On a microprocessor it is also used to store the status register contents before a context switch.

cheers

被你宠の有点坏 2024-08-03 04:30:11

Some microprocessors have stack registers to improve efficiency, take a look at the SPARC article in wikipedia; others have a microstack for the microroutines... It's a very wide term, in fact.

夕色琉璃 2024-08-03 04:30:11

http://www.hobbyprojects.com/microprocessor_systems/images/stack.gif

堆栈是数据的临时存储。

CPU 在处理其他数据时可能会将重要数据压入堆栈。

当它完成该任务时,它将保存的数据从堆栈中拉出。

它就像一堆盘子。
底板是被压入堆栈的第一个数据位。
顶板是最后推送的数据。
最先拉取顶板,最后拉取底板的数据。
它是一个后进先出的堆栈。

在图中,X 首先被推送,然后是 Y,最后是 A。
CPU 去处理其他数据。
该任务完成后,它将返回以提取保存的数据。
首先拉A,然后拉Y,最后拉X。

推送数据的指令是PHA。
只有累加器中的数据才能压入堆栈。
其他数据如果先传输到累加器即可压入。

从堆栈中取出数据的指令是PLA。
堆栈上的数据被传送到累加器。

6502堆栈由256字节组成,占用第1页,地址256到511。

http://www.hobbyprojects.com/microprocessor_systems/images/stack.gif

The stack is a temporary store for data.

The CPU may PUSH important data onto the stack, while it is processing other data.

When it finishes that task, it PULLS the saved data off the stack.

Its like a pile of plates.
The bottom plate is the first bit of data that was pushed onto the stack.
The top plate is the last data to be pushed.
The top plate is pulled first and the bottom plate is the last data to be pulled.
It is a LAST IN, FIRST OUT stack.

In the diagrams, X is the first to be pushed, then Y and lastly A.
The CPU goes away to process other data.
Upon completion of that task it returns to pull the saved data.
First A is pulled, then Y and lastly X.

The instruction for pushing data is PHA.
Only data in the accumulator can be pushed onto the stack.
Other data can be pushed if it is transferred to the accumulator first.

The instruction for pulling data from the stack is PLA.
Data on the stack is transferred to the accumulator.

The 6502 stack consists of 256 bytes and occupies page 1, addresses 256 to 511.

み青杉依旧 2024-08-03 04:30:11

只是为了补充其中一些答案,一些低端微控制器(例如 PIC 系列)具有硬件调用堆栈,这意味着它不能像在硬件中那样动态分配。

这样做的含义是,在堆栈耗尽之前,您只能进行如此多的函数调用; 当然,软件也是如此,但通常基于硬件的堆栈可能非常有限,并且可能需要您重新考虑您的程序以“展平”您的函数调用。

Just to add to some of these answers, some lower-end micros such as the PIC line have a hardware callstack, which means it can not be dynamically allocated as it is in hardware.

The implications of this are that you can only go so many function calls deep before you run out of stack; this is true of software also of course, but often the hardware based stack can be very limiting, and can require you to rethink your program in order to 'flatten' out your function calls.

风吹过旳痕迹 2024-08-03 04:30:11

堆栈是 LIFO(后进先出)缓冲区的实现。 FIFO(先进先出)也称为队列。 但回到后进先出法。

x86 架构中的堆栈允许软件设计人员省去 RISC 处理器中的返回地址寄存器和中断返回地址寄存器等奇怪的东西。 一切都可以驻留在堆栈上,这意味着有一个标准化且统一的方法来处理调用/返回、参数/局部变量和中断/中断返回。 在单独的堆栈上使用该方法简化了多线程的实现。

相比之下,RISC 使用类似堆栈的缓冲区,尽管它们在其他地方保留了相关信息的重要部分。 RISC“堆栈”可能更快(不确定),但它们肯定比 x86 的堆栈更难理解。

A stack is an implementation of a LIFO (Last In - First Out) buffer. The FIFO (First In - First Out) is also known as a queue. But back to the LIFO.

Stacks in the x86 architecture allow software designers to dispense with such strange stuff as return address registers and interrupt return address registers that are found in RISC processors. Everything can reside on the stack which means that there is a single standardized and unified method of handling calls/returns, parameters/local variables and interrupts/interrupt returns. The use of the method on separate stacks simplifies implementation of multi-threading.

RISC, in contrast, uses a stack-like buffer though they keep significatnt parts of the related info elsewhere. RISC "stacks" may be faster (not sure) but they are definitely more difficult to understand than those of the x86.

别忘他 2024-08-03 04:30:11

实际上堆栈并不是处理器的术语,它用于语言的例程调用。 例程可以使用堆栈来获取参数和保存局部变量,也可以调用其他例程。

Actually stack is not a teminology for processor, it is used for language's routine call. A routine can use stack to get parameters and save local variables, also call other routines.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文