当某个东西被推拉出来时,我试图理解堆栈是如何工作的,抱歉,如果这个问题听起来很简单的话。
我想从一些超级基本的东西开始,比如8位内存(我知道这会过于简化,但让我们从简单开始吧)
我设计堆栈的方式如下:
SP将首先指向内存中的最高位置: 0xFF。
0xFF: <- SP
当发出推送命令时,我会将val
保存在SP指出的位置,然后减少SP。
0xFE: <- SP
0xFF: val
pop命令将首先增加SP,然后将SP所指向的值移到寄存器中。
基本上,我的SP指向堆栈中的第一个可用位置。
然而,这似乎不是它在实际系统中的实现方式。
查看组装手册中的推送指令:
Decrements the stack pointer and then stores the source operand on the top of the stack.
因此,基本上SP指向最新的存储值。
我的问题是:首先减少堆栈指针,难道堆栈的顶部就不能使用了吗?如果我们在保存数据之前先减少指针,那么如何将数据存储到堆栈的第一个位置?
是否有理由这样设计堆栈指针?
发布于 2019-07-14 23:45:16
减少堆栈指针,然后将源操作数存储在堆栈顶部。
有一些设计方面的考虑(但请放心,我同意这是相对武断的,因为这两种方法都可以发挥作用):
首先,让我们以您的例子为例,看看如果从一开始就将一个2字节的单词推到堆栈上会发生什么。
0xFF: <- SP
push.w val2
0xFD: <- SP
0xFE: val2(hi 8-bits) # order depends on big/little endian
0xFF: val2(lo 8-bits)
值的8位指向SP所指向的位置(第一个可用字节),而其他8位必须位于该地址以下(因为它们不能高于该地址,嗯?). 堆栈指针被保留为一个空闲字节,所以在SP + 1处刚刚推送的值是可访问的。
虽然这是可行的,但另一种选择似乎更合理:
刚才推送的项目位于SP + 0位置。
请记住,加载比存储更常见,所以加载堆栈顶部项的频率可能比存储高。在支持无位移加载的体系结构中,在SP +0访问堆栈顶部时更倾向于加载。(它还支持声称的空间而不是无人声称的空间。)
如果我们想到SP +?作为索赔和无人认领之间的分界,在索赔空间中加入0似乎更实际、更自然。这是因为(在计算机中,与数学不同),零更像是正数之一,而不是一个负数--例如,考虑无符号数,它总是支持零(以及正值)。
我们还需要注意的是,由于微体系结构的原因,内存读取比内存写入慢(读取通常在临界路径上,这限制了最大可能的时钟频率,而写入不是). ,因此,增量后pop (负载)比增量前pop更好,因为增量后的pop可以在并行硬件(数据内存访问)中进行加法,而增量前pop在地址总线和数据存储器读取操作中放置加法器。(当然,为了支持增量后pop,我们需要预减量推送。)
发布于 2019-07-15 07:44:11
为什么首先推送减少堆栈指针?
首先,这取决于CPU类型,堆栈指针是如何工作的。
在6800上,首先写入值,然后减少堆栈指针。
在TMS320F28上,写入值,然后增加堆栈指针。
..。堆栈的顶部不是不能用吗?
请忘记“不可用”这个词。正确的词应该是“使用中”。
请考虑下面的C或Java程序:
int a, b;
a = someFunction();
someOtherFunction();
thirdFunction(a);
您希望将someOtherFunction()
的返回值存储在一个变量中,如下所示:
int a, b;
a = someFunction();
a = someOtherFunction();
thirdFunction(a);
这不是一个好主意,因为变量a
已经“在使用”了。然而,变量b
仍然是“可用的”。
但是,这并不妨碍您覆盖变量a
。
现在让我们回到堆栈指针,看看局部变量。查看局部变量(而不是push
),我们可以更清楚地看到堆栈指针实际上做了什么:
当输入这样的函数时:
void someFunction(void)
{
int x, y, z;
...
y = 5;
}
..。生成的汇编程序代码首先将堆栈指针减少3(假设一个int
需要一个内存位置)。
假设堆栈指针在输入函数之前具有0x73值。这意味着内存位置0.72“不在使用”,而内存位置73...FF“在使用”。
汇编程序代码将堆栈指针的值更改为0x70,并将变量x
存储在地址0x70,y
存储在地址0x71,z
存储在0x72。
堆栈指针的值为0x70,这意味着内存位置70...FF现在“在使用”。
应该清楚的是,内存位置70.72“正在使用”,因为变量x
、y
和z
都存储在那里。
但是,这并不意味着无法访问(读或写)这些内存位置:指令y=5;
将写入内存位置0x71。
https://stackoverflow.com/questions/57031401
复制相似问题