32位ARM堆栈:为什么SP的最低有效2位必须始终为0?

32位ARM堆栈:为什么SP的最低有效2位必须始终为0?,arm,stack,Arm,Stack,我不熟悉堆栈并试图掌握它,堆栈指针的这句话已经困扰了我好几个小时了: 在ARM Cortex-M处理器上,堆栈始终在32位数据上运行。所有堆栈访问都是字对齐的,这意味着SP(堆栈指针)的最低有效两位必须始终为0 我知道堆栈只是RAM的一部分,RAM包含32位数据,所以所有的操作,比如PUSH/POP,都需要32位操作。关于该声明,我有两个问题: 所有堆栈访问都是“字”对齐的。是否应该用DWORD而不是WORD来弥补32位?如果不是,为什么所有堆栈访问都是字或16位而不是32位 为什么它意味着SP

我不熟悉堆栈并试图掌握它,堆栈指针的这句话已经困扰了我好几个小时了:

在ARM Cortex-M处理器上,堆栈始终在32位数据上运行。所有堆栈访问都是字对齐的,这意味着SP(堆栈指针)的最低有效两位必须始终为0

我知道堆栈只是RAM的一部分,RAM包含32位数据,所以所有的操作,比如PUSH/POP,都需要32位操作。关于该声明,我有两个问题:

  • 所有堆栈访问都是“字”对齐的。是否应该用DWORD而不是WORD来弥补32位?如果不是,为什么所有堆栈访问都是字或16位而不是32位

  • 为什么它意味着SP的最低有效两位必须始终为零

  • 有什么想法吗?

    1)所有堆栈访问都是“word”对齐的。是否应该用DWORD而不是WORD来弥补32位?如果不是,为什么所有堆栈访问都是字或16位而不是32位?

    字的大小取决于CPU体系结构。在32位Cortex-M上,一个字由32位或4个字节组成。

    2) 为什么它意味着SP的最低有效两位必须始终为零?

    这是一种不同的方式,表示堆栈应始终在4字节边界上对齐,或者堆栈指针应始终包含4字节的倍数地址。


    例如,二进制地址0000是0十进制。接下来的三个地址0001(1十进制)、0010(2十进制)和0011(3十进制)二进制地址的最低有效位设置为01、10和11。0100(4位小数)是0000后面的第一个地址,其两个最低有效位设置为0:这与说它是4字节的倍数,或者如果您愿意,是CPU字大小(字节)的倍数是一样的。

    在大多数32位体系结构中,字是32位的。x86是一个例外,因为它最初是16位体系结构,所以x86中的“word”表示16位。谢谢你的解释,我现在有点明白了。嗨,弗兰特,谢谢你的解释,我现在有点明白了,尽管我对你对问题2的回答仍然感到困惑。SP是一个32位指针,因此它包含一个4字节倍数的地址。根据您的解释,似乎每个SP将覆盖堆栈中的4个地址?例如SP将覆盖0x00000000、0x00000001、0x00000002、0x00000003?但如果是这种情况,如果我想,SP如何访问0x00000001位置?我的理解是,只能通过读取/写入整个单词来访问堆栈。基本上,您将推/弹出完整的32位寄存器。现在,如果您想使用存储在寄存器(而非SP)中的地址读取特定字节,请参阅此处的LDRSB示例:您将在本段中了解到,SP只能在读取/写入整个字时使用,即在LDR指令中,而不是LDRB或LDRH指令中。我相信arm约定需要64位对齐堆栈btw,如果查看编码,则指令集PUSH和pops实际上是stm和ldm指令,因此必须(32位)对齐。没有理由不能将堆栈指针移动到其他寄存器,然后对堆栈上的局部变量执行strb/ldrb。堆栈帧指针。