C函数调用约定:为什么movl而不是pushl



我不明白为什么下面的行使用movl来推送堆栈指针下面的数据是由GCC生成的。

movl    -4(%ebp), %eax      # -4(%ebp) <- local variable 1
movl    8(%ebp), %edx       # 8(%ebp)  <- first parameter
movl    %edx, 8(%esp)       # ??? WHY NOT:   pushl %edx
movl    %eax, 4(%esp)       # ??? WHY NOT:   pushl %eax
movl    -8(%ebp), %eax      # ??? WHY NOT:   pushl -8(%ebp)
movl    %eax, (%esp)
call    athena
movl    %eax, f

(完整代码)

我猜这段代码试图为函数调用推送3个参数。但是为什么不使用pushl呢。这个代码的用途是什么?它是如何工作的?

Hans Passant回答正确。推/弹出操作码可以分解为两个微操作,分别进行内存移动和堆栈指针的递增/递减。如果堆栈指针(或任何指针)被更新,然后立即在下一个操作码中使用,则通常会发生执行暂停。通过堆栈指针访问各个内存位置(如您的示例中所示),将不会出现停滞,并且操作可以配对,从而允许它们同时执行。

任何超标量CPU类型都将尝试在一个周期内执行多个操作码,如果它们的结果/源彼此无关。编译器正在为您做一些加快执行速度的事情,而手工操作会相当费力。操作码可能比推送占用更多的空间,但它们的执行速度大约是推送的两倍——所有其他东西都是一样的。

最新更新