gpt4 book ai didi

从 x86_64 程序集调用 memset

转载 作者:太空宇宙 更新时间:2023-11-03 23:27:54 24 4
gpt4 key购买 nike

我正在尝试通过查看从 clang 生成的程序集来学习 x86 程序集。例如,我想了解如何将 C 中的自动数组初始化为全 0。

int64_t my_array [3000] = {0};

看起来程序集在堆栈上保留 24000B ( 3000 * 64b/8B/b ) 然后调用 memset。在 memset 的手册页中,它的签名如下所示:

void *
memset(void *b, int c, size_t len);

所以我知道应该在 %rsi 中传递的第二个参数是 0(我希望每个字节都设置为该值),第三个参数 (%rdx) 应该是 $24000,但是第一个参数 (%rdi) 呢? )?生成的程序集中的两条相关指令似乎是:

leaq  -24016(%rbp), %rax
movq %rax, %rdi

但我不明白为什么基指针的负值 24016?为什么存储在 %rax 中然后立即移动到 %rdi(可能是因为我没有进行优化编译)?

无论哪种方式,我都不确定如何将数组第一个字节的地址传递给 memset。我也在 OSX 上,所以我已经不得不将我的堆栈指针偏移 8B 才能进行汇编。

最佳答案

您已经在堆栈(自动存储)上分配了 my_array,这意味着编译器必须将堆栈指针(堆栈向较低地址增长)递减您的局部变量的大小加上空间保存寄存器等。 %ebp 基指针设置为指向调用者的帧指针(通过将调用者的基指针压入堆栈来保存它之后)。这是正确堆栈展开所必需的约定的一部分。请参阅 Agner Fog 的综合调用约定文档中的第 9 章异常处理和堆栈展开

http://www.agner.org/optimize/calling_conventions.pdf .

由于 %ebp 指向调用者的帧,编译器使用它的负偏移量指向 my_array 的开头,这是被调用函数中的局部变量.

我不知道为什么编译器将地址存储在 %rax 中并立即将其复制到 %rdi,似乎它可以做到这一点一步到位

leaq  -24016(%rbp), %rdi

关于从 x86_64 程序集调用 memset,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22626182/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com