Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pointers 在程序集中移动堆栈指针_Pointers_Assembly_Stack - Fatal编程技术网

Pointers 在程序集中移动堆栈指针

Pointers 在程序集中移动堆栈指针,pointers,assembly,stack,Pointers,Assembly,Stack,我不明白,如果要在堆栈上分配8字节的存储,为什么要使用以下命令 subq $8,%rsp %rsp存储一个地址。为什么从%rsp中存储的地址中减去文本值8会分配8个字节?特别是,为什么$x对应于x字节 编辑:我的问题在这篇文章中得到了回答。它是以字节为单位的,因为这是一个int的大小,int是传入的文本参数 编辑2:上述内容不正确。见薄熙来的评论。你说得对。堆栈指针只是指向内存地址的指针。该内存块实际上是在线程初始化时作为一个大块分配的。它通常足够大,以避免堆栈溢出。堆栈指针在开始处指向该块的

我不明白,如果要在堆栈上分配8字节的存储,为什么要使用以下命令

subq $8,%rsp
%rsp存储一个地址。为什么从%rsp中存储的地址中减去文本值8会分配8个字节?特别是,为什么$x对应于x字节

编辑:我的问题在这篇文章中得到了回答。它是以字节为单位的,因为这是一个int的大小,int是传入的文本参数


编辑2:上述内容不正确。见薄熙来的评论。

你说得对。堆栈指针只是指向内存地址的指针。该内存块实际上是在线程初始化时作为一个大块分配的。它通常足够大,以避免堆栈溢出。堆栈指针在开始处指向该块的末尾,每当推送新值时,堆栈指针将递减(每当弹出新值时,堆栈指针将递增)。将一个值推送到堆栈只会将给定值移动到SP指向的内存插槽,并使其递减。例如:

push rax 
等同于:

sub rsp, 8
mov [rsp], rax
只有从SP中减去(而不是执行
推送
)实际上会在堆栈中留下一个可用空间,供您自己使用。这就是局部变量的工作原理。因此:

sub rsp, 16
将堆栈指针向下移动16个字节,这样您就有了16个字节的空间,您可以在自己的函数中使用它们。要释放它,您需要记住相应地增加rsp或使用帧指针,如:

mov rbp, rsp
sub rsp, 16
; and here access the values using rbp-xxx instead of rsp+xxx

mov rsp, rbp
因此,编译器可以执行
push rax
而不是
sub-rsp,8
,但这实际上需要写入内存(因为rax的内容需要存储)。那将是一种浪费。相反,在真正需要内存块之前,移动指针本身是一种便宜得多的操作


(如果我在这里使用的英特尔汇编语法造成混乱,请告诉我,我只是觉得编写起来容易多了)

你说得对。堆栈指针只是指向内存地址的指针。该内存块实际上是在线程初始化时作为一个大块分配的。它通常足够大,以避免堆栈溢出。堆栈指针在开始处指向该块的末尾,每当推送新值时,堆栈指针将递减(每当弹出新值时,堆栈指针将递增)。将一个值推送到堆栈只会将给定值移动到SP指向的内存插槽,并使其递减。例如:

push rax 
等同于:

sub rsp, 8
mov [rsp], rax
只有从SP中减去(而不是执行
推送
)实际上会在堆栈中留下一个可用空间,供您自己使用。这就是局部变量的工作原理。因此:

sub rsp, 16
将堆栈指针向下移动16个字节,这样您就有了16个字节的空间,您可以在自己的函数中使用它们。要释放它,您需要记住相应地增加rsp或使用帧指针,如:

mov rbp, rsp
sub rsp, 16
; and here access the values using rbp-xxx instead of rsp+xxx

mov rsp, rbp
因此,编译器可以执行
push rax
而不是
sub-rsp,8
,但这实际上需要写入内存(因为rax的内容需要存储)。那将是一种浪费。相反,在真正需要内存块之前,移动指针本身是一种便宜得多的操作


(如果我在这里使用的英特尔汇编语法造成混乱,请告诉我,我只是觉得编写起来容易多了)

为什么不呢?我的意思是,我想知道有什么是不清楚的?指针被放入堆栈中。如果将指针向后移动八个字节,则会创建一个八字节的孔来使用。我不明白为什么文字值是以字节为单位解释的。因为最小的内存单位是byteNo。另一个问题是关于C中的类型指针,它的工作方式与无类型程序集中的地址不同。
$8的类型与结果无关,它只是值8。在x86硬件上,内存单元是字节,所以我们只计算字节。有些字地址系统的内存单元可能是16或32位。在那里,它的工作方式会有所不同。@AisforAmbition-Assembly是非类型化的,因此您对rax的操作取决于您对结果的解释。它可以是任何东西。然而,rsp肯定是一个指针,所以它包含一个内存地址。由于rsp的大小,您必须使用subq。使用subb根本不起作用,为什么不呢?我的意思是,我想知道有什么是不清楚的?指针被放入堆栈中。如果将指针向后移动八个字节,则会创建一个八字节的孔来使用。我不明白为什么文字值是以字节为单位解释的。因为最小的内存单位是byteNo。另一个问题是关于C中的类型指针,它的工作方式与无类型程序集中的地址不同。
$8的类型与结果无关,它只是值8。在x86硬件上,内存单元是字节,所以我们只计算字节。有些字地址系统的内存单元可能是16或32位。在那里,它的工作方式会有所不同。@AisforAmbition-Assembly是非类型化的,因此您对rax的操作取决于您对结果的解释。它可以是任何东西。然而,rsp肯定是一个指针,所以它包含一个内存地址。由于rsp的大小,您必须使用subq。使用subb根本不起作用。