gpt4 book ai didi

assembly - 无堆栈函数的跳转/跳转编译策略。 (手动使用链接注册而不是调用/返回)

转载 作者:行者123 更新时间:2023-12-04 08:21:49 31 4
gpt4 key购买 nike

我熟悉构建函数序言/结尾的两种基本策略:

  1. “常规”函数:将堆栈指针移动到堆栈帧的末尾(sub rsp, n),执行实际工作,然后将堆栈指针移回(add rsp , n) 和 ret。 (如果正文中使用了很多寄存器,这里可能还会有一些插入和弹出。)
  2. “叶子”功能:与(1)相同但不移动堆栈指针,节省两条指令。

使用策略 2,您不能在主体内调用函数,除非您将堆栈指针移动到它应该在的位置,这会破坏节省,这就是为什么它通常只用于叶函数。

但我想到还有第三种策略可以使用:

  1. “Stackless”函数:使用 mov rsi, AFTER;跳跃功能; AFTER: 用于调用顺序,在函数中只是 jump rsi 最后。

在这个方法中,我们完全忽略了堆栈指针,所以我们没有堆栈空间,但对于一个可能可行的小函数。它还需要自定义调用约定,但如果编译器需要内部函数,则可以这样做。

因为它把 jumpjump 配对,所以它不会触及返回堆栈,所以分支预测器不应该被丢弃(尽管最后的间接跳转可能比返回慢),并且 call 不会产生内存写入开销。此外,stackless 函数可以调用其他 stackless 函数(虽然不会太多,因为您最终会用完用于存储返回地址的寄存器,并且存在全局优化问题以确保如果 A 调用 B 然后它们使用不同的返回寄存器) .

我的问题是:为什么编译器不多使用方法 (3)? AFAICT 在查看由 gcc 或 clang 编译的函数时,它永远不会出现。是否有此调用约定不可用的原因?

最佳答案

这是对这两个选项进行基准测试的尝试。

    .text
.align 8

subroutine:
inc %rdx
#ifdef REG_CALL
jmp *%rsi
#else
ret
#endif

reps = 1000000
.global main

main:
push %rbp
mov $reps, %ecx
xor %edx, %edx
.align 8
top:
.rept 1000
#ifdef REG_CALL
lea 0f(%rip), %rsi
jmp subroutine
0:
#else
call subroutine
#endif
.endr
dec %ecx
jnz top

lea format(%rip), %rdi
mov %rdx, %rsi
xor %eax, %eax
call printf
xor %eax, %eax
pop %rbp
ret

.data
format: .asciz "%ld calls done\n"

它从不同的返回地址调用子例程 1000 次,重复一百万次。组装时没有传统 call/ret 的选项,使用 -DREG_CALL 作为间接跳转建议。

在 i7-8565U CPU @ 1.80GHz 上,传统方式需要 1.6 秒,REG_CALL 需要大约 3.2 秒。所以你的提议似乎慢了一倍。

正如我在评论中提到的,我怀疑 the indirect branch predictor can't keep track jmp *%rsi 要去的地方。

除了运行时效率低下,Raymond Chen mentions another major disadvantage of this strategy in the comments :

Another problem is register assignment if one stackless function calls another. Not only must they use separate return address registers, their other register usages cannot conflict either. This would be practical only for small functions with few callers, at which point you may as well just inline them.

关于assembly - 无堆栈函数的跳转/跳转编译策略。 (手动使用链接注册而不是调用/返回),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65461332/

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