assembly 如何在NASM x86-64中为堆栈赋值而不越界?

xiozqbni  于 2023-05-29  发布在  其他
关注(0)|答案(1)|浏览(141)

我想了解如何在NASM x86-64中正确分配堆栈上的值
我想澄清一些事情。想象一下,我们有一个这样的汇编程序,有一个prologue + epilogue和一个16字节的预留:

push rbp
mov rbp, rsp
sub rsp, 16
mov [rbp - 8], rdi
mov [rbp - 16], rsi
add rsp, 16
pop rbp
ret

我想理解的是,在约定中,RSP被标记为指向堆栈上分配的最后一个元素的末尾。我怎么能归因于[rbp - 16],rsi?既然这是我定义的段的结尾?

nzk0hqpo

nzk0hqpo1#

RSP指向堆栈上分配的最后一个元素的end
“结束”这个词引起了混淆。
通常,当查看内存块时,它“开始”于范围中的最低地址,并“结束”于范围中的最高地址。

0 ...  <-------------------------->  ...
       |                           |
       Begin                       End

堆栈的不同之处在于堆栈向下生长。您所做的新分配从某个较高的地址“开始”,并在较低的地址“结束”。这就是你引用的“结束”。

0 ...  <-------------------------->  ...
       |                           |
       End                         Begin
       New RSP                     Old RSP
       Top-Of-Stack

为了增加混乱,这个较低的地址现在被命名为Top-Of-Stack,这对于单词“top”来说肯定也不直观。(如果堆栈向上生长,则不会存在任何混淆......)

push rbp
mov rbp, rsp
sub rsp, 16
mov [rbp - 8], rdi
mov [rbp - 16], rsi

您的代码段包含2个堆栈内存分配:push rbp请求8字节,sub rsp, 16请求16字节。一旦分配,您就可以自由地从/向该内存进行读取/写入。在push rbp的情况下,是CPU写入内存。

0 ...  <---RSI------RDI------RBP-->  ...
       |         |        |        |
       End       |        |        Begin
       New RSP   |        |        Old RSP
       New Top-Of-Stack   |        Old Top-Of-Stack
       |         |        |
       [RBP-16]  [RBP-8]  [RBP]

相关问题