热门问题
时间线
聊天
视角
堆叠暂存器
来自维基百科,自由的百科全书
Remove ads
堆叠暂存器是微处理器中,处理呼叫堆叠的暂存器。在以累加器为基础的处理器中,堆叠暂存器可能是某个特定的暂存器。若是有多个通用暂存器的处理器架构,堆叠暂存器可能是某个依惯例保留的暂存器,像是IBM System/360、z/Architecture架构以及RISC架构,也有可能是用副程式呼叫或程式返回指令,硬编码的暂存器,例如PDP-11、VAX和Intel x86架构。有些处理器(像Data General Eclipse)没有专用的堆叠暂存器,而是用保留的硬体记忆体位置来处理此功能。
在1960年末期以前的处理器(例如PDP-8和HP 2100)没有可以支援递归呼叫的编译器。其程序呼叫指令会将目前程式指标位置储存在跳跃地址,接著将程式指标设定为下一个位置[1]。此作法比维护堆叠简单,因为每一个副程式只会有一个返回位址,但除非程式作大幅相关更动,此作法无法支援递归呼叫。
堆叠结构机器(Stack machine)可能会有二个或多个堆叠暂存器,其中有一个处理呼叫堆叠,其他暂存器则处理其他堆栈。
Remove ads
x86的堆叠暂存器
x86架构16位元的处理器里,主堆叠暂存器是16位元的堆叠指标(Stack Pointer,SP), 32位元的IA-32里,扩展为32位元的扩展堆叠指标(Extended Stack Pointer, ESP),64位元的X86-64里,扩展为64位元的暂存器堆叠指标(Register Stack Pointer,RSP)。堆叠区段暂存器(stack segment register,SS)会储存目前执行程式呼叫堆叠的记忆体分段相关资讯。SP会指向目前堆叠的最顶端。预设情形,堆叠会以记忆体减少的方式成长,因此比较新的资料会放在较低的记忆体位置。PUSH
指令可以将值存在堆叠里,因此堆叠会增加一个资料,POP
指令可以提取堆叠中的资讯,并且堆叠会减少一笔资料。
假设SS = 1000h,SP = 0xF820,这表示目前的堆叠顶是在实体地址0x1F820(这是因为Intel 8086的记忆体分区机制),接下来的二个机器码是
PUSH AX
PUSH BX
- 第一个指令会将AX(16位元暂存器)的值放在堆叠内,SP数值会减2。
- 新的SP值是0xF81E。CPU会将AX的值复制到0x1F81E.
- 执行PUSH BX时,会设定SP为0xF81C,将BX的值复制到0x1F81C[2]。
上述就是PUSH运作的原理。一般来说,程式将暂存器的资料PUSH到堆叠是有其目的,例如呼叫会更改暂存器值的副程式。若要提取堆叠中的程式,可以用以下的机器码
POP BX
POP AX
Remove ads
堆叠机
较简单的处理器会将堆叠指标储存在一般的硬体暂存器,用算术逻辑单元(ALU)来处理其数值。一般来说push和pop会翻译为多个微指令,去增加或减少堆叠指标,处理记忆体的读取和写入[3]。
较新的处理器会有专用的堆叠机(stack engine)以最佳化堆叠操作。Intel的Pentium M是第一个有堆叠机的x86处理器,其实现方式是将堆叠指标分为两个暂存器:ESPO是32位元的暂存器,ESPd是8位元的偏移值,会依堆叠操作而更新其数值。PUSH、POP、CALL和RET微指令直接对ESPd运作。若If ESPd接近溢位,或是ESP暂存器被其他指令更新(而ESPd ≠ 0),此时会插入同步的微指令,用ALU更新ESPO,并且让ESPd为0。在后续的Intel处理器中,此机制大致保留,不过将ESPO扩充到64位元[4]。
AMD K8微处理器使用一种类似于Intel堆叠机的作法。在其推土机微架构中,不需要加入同步的微指令,但不清楚其堆叠机的内部设计[4]。
Remove ads
注解
参考资料
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads