存储到堆栈地址的双字是不是会影响地址+0..3 或地址-0..3 处的字节?

Posted

技术标签:

【中文标题】存储到堆栈地址的双字是不是会影响地址+0..3 或地址-0..3 处的字节?【英文标题】:Does a dword store to a stack address affect bytes at address+0..3 or address-0..3?存储到堆栈地址的双字是否会影响地址+0..3 或地址-0..3 处的字节? 【发布时间】:2021-04-21 10:14:12 【问题描述】: 在 x86 架构(比如 32 位)中,地址是否只指向一个字节?意思是,如果我们查看地址 0x0000 0000 0000 FFFF 是不是只有一个字节?我认为答案是肯定的,但需要确认

我想知道这条指令的值是如何存储的,movl %eax, -4(%rbp)。我的理解是我们将堆栈中的值放在基指针的较低地址。

由于 eax 是 32 位,当我们进行操作时,它实际上是如何显示在堆栈上的?意思是,如果eax有0x0a0b0c0d,并且使用小端序是这个吗?

rbp[-4]   0d           ; low byte at given address
rbp[-3]   0c
rbp[-2]   0b
rbp[-1]   0a           ; dword ending here

还是这个?

rbp[-7]   0d
rbp[-6]   0c
rbp[-5]   0b
rbp[-4]   0a          ; high byte at given address, dword ending here

或 其他的,因为我不明白?任何帮助都会很棒

【问题讨论】:

别想太多。加载和存储总是从多字节内存数据的最低(数字)地址计算和工作。向下增长的堆栈不会改变这一点。负位移寻址不会改变这一点。 【参考方案1】:

每个字节都有自己的地址,所以从这个意义上说,地址 0x12345678 只有一个字节。但是,我们通常会说“地址 0x12345678 处的双字”。这意味着由地址 0x12345678、0x12345679、0x1234567a、0x1234567b 处的字节组成的 4 字节双字,最低有效在前。

所以这取决于您所说的“查看地址”是什么意思。例如,如果您要求调试器显示地址 0x12345678 的内容,并且它设置为显示双字,它将显示一个 4 字节双字,但这并不意味着该双字的所有 4 个字节都位于地址 0x12345678 .

因此,您对movl %eax, -4(%rbp) 的两个猜测中的第一个是正确的。对于大于一个字节的加载和存储,给定地址指向要访问的对象的最低地址字节。

请注意,这使得对齐计算工作得很好:对齐的双字是一个地址是 4 的倍数,因此双字地址的低 2 位为零。在 C 语言中((uintptr_t)&intvar) % 4 == 0,对于 alignof(int) == 4。另一种方式意味着对于对齐的对象,低 n 位必须全为 1。

【讨论】:

【参考方案2】:

是的,不是的。寻址粒度是一个字节,所以是的,地址0x0000 0000 0000 FFFF 指向一个字节,其前一个字节用0x0000 0000 0000 FFFE 寻址,其后一个字节用0x0000 0000 0001 0000 寻址。然而,我们也可以从同一个地址加载一个 16 位字,而不是一个字节。 例如,指令MOV AX,[0x0000_0000_0000_FFFF] 将从0x0000 0000 0000 FFFF 加载AL 和从0x0000 0000 0001 0000 加载AH。在这种情况下,0x0000 0000 0000 FFFF 正在处理一个词。类似地,更长的数据类型可以用相同的数字来处理(尽管在此架构中始终建议对齐,有时甚至是强制性的)。

如果EAX 包含值 0x0a0b0c0d,则AL=0x0DAH=0x0C 等。 movl %eax, -4(%rbp) 别名 MOV [RBP-4],EAX 在 Intel 语法中,会将 32 位双字存储到地址 [RBP-4],即 AL=0x0D 转到 [RBP-4]AH=0x0C 转到 [RBP-3] 等。

【讨论】:

以上是关于存储到堆栈地址的双字是不是会影响地址+0..3 或地址-0..3 处的字节?的主要内容,如果未能解决你的问题,请参考以下文章

找出有多少字节将 esp 和程序堆栈上存储的返回地址分开

将地址存储到向量中的堆栈分配对象

.NET - 存储在地址空间中的堆或堆栈上的函数变量?

存储器的保护——《x86汇编语言:从实模式到保护模式》读书笔记20

如何从文本语料库中删除特定的单字组,但仍保留该单词的双字组?

堆地址是不是共享堆栈地址?