为什么Rust使用RSI将参数传递给FN指针

Austaras:

对于普通功能,rust的行为与x86-64 abi相同,后者通过参数使用以rdi开头的寄存器进行传递,但是对于fn指针rust使用rsi,那么为什么rustc选择这样做?

以这个为例

fn foo(f: fn(u64)) {
    f(10);
}

fn main() {
    foo(|i| {
        i + 1;
    });
}

闭包被编译为

playground::main::{{closure}}:
    sub rsp, 24
    mov qword ptr [rsp + 8], rdi
    mov qword ptr [rsp + 16], rsi
    add rsi, 1
    setb    al
    test    al, 1
    jne .LBB11_2
    add rsp, 24
    ret

在正常功能foo编译为

playground::foo:
    sub rsp, 24
    mov qword ptr [rsp + 16], rdi
    mov eax, 10
    mov qword ptr [rsp + 8], rdi
    mov rdi, rax
    mov rax, qword ptr [rsp + 8]
    call    rax
    add rsp, 24
    ret

使用rdi并调用它main

    lea     rdi, [rip + core::ops::function::FnOnce::call_once]
    call    playground::foo

所以这通过调用core::ops::function::FnOnce::call_once来完成

core::ops::function::FnOnce::call_once:
    sub rsp, 40
    mov qword ptr [rsp + 16], rdi
    mov rsi, qword ptr [rsp + 16]
    lea rdi, [rsp + 8]
    call    playground::main::{{closure}}
    jmp .LBB4_1

.LBB4_1:
    jmp .LBB4_2

.LBB4_2:
    add rsp, 40
    ret
用户1937198:

纯粹是推测,但闭包可能总是使用带有&self的固有方法编译为结构,然后生成包装程序以将其转换为函数指针。这将允许固有方法也称为传递数据指针的特征对象。包装器的参数在rdi中传递,然后rdi分配堆栈空间以存储合成的零大小结构。然后,该包装程序在rdi中传递合成的结构,并在下一个参数槽rsi中传递参数。在优化的代码中,可以期望将固有方法内联到包装器中,并且可以消除与寄存器合成奇怪参数的怪异舞步。

简而言之,这是常规系统v的调用约定,但是还有一个永不读取的隐式参数,因此所有实际参数都将与常规参数一起沿列表进一步移位一个寄存器。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么在声明使用命名空间std时将int用作指针参数传递给函数?

来自分类Dev

为什么将取消引用的指针传递给指针类型?

来自分类Dev

为什么可以将未初始化的变量地址传递给函数的指针参数

来自分类Dev

函数为什么要在传递给它的参数上使用“运算符的地址”作为指针?

来自分类Dev

为什么将指针传递给具有常量指针类型参数的函数时不需要类型转换?

来自分类Dev

为什么我们不允许将纯引用参数传递给std :: thread但允许传递原始指针?

来自分类Dev

当您可以直接将指针传递给C函数时,为什么要使用memcpy()?

来自分类Dev

使用可变参数模板将指针传递给成员

来自分类Dev

在C语言中,为什么我可以将函数名称(而不是指针)作为参数传递给函数?

来自分类Dev

为什么将参数传递给g ++的顺序很重要

来自分类Dev

为什么将参数传递给$ uibModalInstance.close(parameter)?

来自分类Dev

为什么将结构传递给函数而不是单独的参数?

来自分类Dev

为什么 PHP 要求将参数传递给匿名类?

来自分类Dev

为什么不能使用模板模板参数将std :: vector <MyType>传递给此函数?

来自分类Dev

何时将指针参数传递给函数

来自分类Dev

将指针或副本的参数传递给函数

来自分类Dev

为什么Box指针传递给C并返回Rust分段错误?

来自分类Dev

C ++:为什么我可以将指针值成员变量从const成员函数传递给采用非const指针参数的外部函数?

来自分类Dev

使用ctypes将类型指针的参数传递给C函数的指针

来自分类Dev

为什么使用Messenger而不是将引用传递给Handler?

来自分类Dev

通过引用将指针参数传递给函数是什么意思?

来自分类Dev

将指针作为参数传递给函数的正确方法是什么?

来自分类Python

Python,如何将参数传递给函数指针参数?

来自分类Dev

将指针传递给函数并使用realloc

来自分类Dev

为什么可以将双指针(地址地址)传递给scanf?

来自分类Dev

为什么将闭包传递给接受函数指针的函数不起作用?

来自分类Linux

为什么不使用RCX将参数传递给系统调用,而用R10代替?

来自分类Dev

为什么将“ switch”类型参数的值传递给字符串参数?

来自分类Dev

为什么将“this”指针直接传递给存档错误,但另一个相同类型的指针可以?

Related 相关文章

  1. 1

    为什么在声明使用命名空间std时将int用作指针参数传递给函数?

  2. 2

    为什么将取消引用的指针传递给指针类型?

  3. 3

    为什么可以将未初始化的变量地址传递给函数的指针参数

  4. 4

    函数为什么要在传递给它的参数上使用“运算符的地址”作为指针?

  5. 5

    为什么将指针传递给具有常量指针类型参数的函数时不需要类型转换?

  6. 6

    为什么我们不允许将纯引用参数传递给std :: thread但允许传递原始指针?

  7. 7

    当您可以直接将指针传递给C函数时,为什么要使用memcpy()?

  8. 8

    使用可变参数模板将指针传递给成员

  9. 9

    在C语言中,为什么我可以将函数名称(而不是指针)作为参数传递给函数?

  10. 10

    为什么将参数传递给g ++的顺序很重要

  11. 11

    为什么将参数传递给$ uibModalInstance.close(parameter)?

  12. 12

    为什么将结构传递给函数而不是单独的参数?

  13. 13

    为什么 PHP 要求将参数传递给匿名类?

  14. 14

    为什么不能使用模板模板参数将std :: vector <MyType>传递给此函数?

  15. 15

    何时将指针参数传递给函数

  16. 16

    将指针或副本的参数传递给函数

  17. 17

    为什么Box指针传递给C并返回Rust分段错误?

  18. 18

    C ++:为什么我可以将指针值成员变量从const成员函数传递给采用非const指针参数的外部函数?

  19. 19

    使用ctypes将类型指针的参数传递给C函数的指针

  20. 20

    为什么使用Messenger而不是将引用传递给Handler?

  21. 21

    通过引用将指针参数传递给函数是什么意思?

  22. 22

    将指针作为参数传递给函数的正确方法是什么?

  23. 23

    Python,如何将参数传递给函数指针参数?

  24. 24

    将指针传递给函数并使用realloc

  25. 25

    为什么可以将双指针(地址地址)传递给scanf?

  26. 26

    为什么将闭包传递给接受函数指针的函数不起作用?

  27. 27

    为什么不使用RCX将参数传递给系统调用,而用R10代替?

  28. 28

    为什么将“ switch”类型参数的值传递给字符串参数?

  29. 29

    为什么将“this”指针直接传递给存档错误,但另一个相同类型的指针可以?

热门标签

归档