程序集中的冗余值复制?

Dev*_*wal 2 optimization x86 assembly micro-optimization

我正在从《Programming Ground Up》一书中学习x86汇编。在介绍函数时,作者给出了一个函数示例,该函数将给定的4字节整数提高为大于0的幂。这是函数的定义方式(这是我编写的版本,但是代码几乎相同):

 1. .type find_pow, @function
 2. find_pow:
 3. pushl %ebp          # Save current base pointer
 4. movl %esp, %ebp     # Copy stack pointer to base pointer
 5. movl $1, %eax        # %eax will hold the result, set it to 1
 6.
 7. subl $4, %esp
 8. movl 8(%ebp), %ebx
10. movl 12(%ebp), %ecx
11.
12. movl %ebx, -4(%ebp)
13.
14. loop_find_pow:      # Start loop
15. cmpl $1, %ecx        # If 2nd parameter equals 0
16. je exit_find_now    # Exit loop
17. movl -4(%ebp), %eax # Move current result to %eax
18. imull %ebx, %eax    # Multiply to current value of %eax
19. movl %eax, -4(%ebp) # Store current result
20. decl %ecx           # Decrease %ecx
21. jmp loop_find_pow   # Jump to loop top
22.
23. exit_find_now:
24. movl -4(%ebp), %eax
25. movl %ebp, %esp
26. popl %ebp
27. ret
Run Code Online (Sandbox Code Playgroud)

我完全理解了代码,但是对于作者为什么要执行第17 ... 19行中的操作有些困惑。首先,将局部变量的值复制到%eax堆栈中。然后使用%eax(我想这是出于性能原因?)完成计算,然后将计算出的值存储回分配给唯一局部变量的空间。我不明白为什么需要所有这些复制。调用者%eax仍然通过检查寄存器来获取返回值。完全消除对局部变量的使用(在地址处有意义-4(%ebp)吗?

编辑:如果有人想看书中的原始代码,请浏览至第67页。

Jon*_*art 6

完全消除使用局部变量(在地址-4(%ebp)处)是否有意义?

是。

由于eax易失性寄存器(由ABI定义),因此该功能无需保留其原始值。

这种简单的算法可以将其所有状态保存在寄存器中,而不必将其溢出到堆栈中。

但是,这是一个简单的示例,打算教。它演示的一件事是当没有足够的寄存器时如何使用堆栈变量。