如果我将它作为参数传递,函数调用的结果保存在哪里?

Where the result of function call is kept if I pass it as parameter?

uint32_t sum_a_b(uint32_t a, uint32_t b) {
    return a + b; 
}

uint32_t mul_c_d(uint32_t c, uint32_t d) {
    return c * d; 
}

int main(uint16_t argc, char **argv) {
    uint32_t e;
    e = mul_c_d(116, sum_a_b(17, 992));
    return 0;
}

问题是 运行 机器在将调用 sum_a_b(17, 992) 的结果作为第二个参数传递给 mul_c_d 之前存储在哪里?

堆栈中有一些“临时变量”?

处理器寄存器?堆?

我在哪里可以读到这篇文章?

与显式使用变量的任何区别,

int main(uint16_t argc, char **argv) {
    uint32_t e, t;
    t = sum_a_b(17, 992);
    e = mul_c_d(116, t);
    return 0;
}

??

不幸的是我没有足够的asm / disasm技能来直接检查它....

谢谢!!

C 标准没有指定变量和值的存储位置,因此结果将是系统特定的。

“堆栈中有一些“临时变量”?”有可能。
“处理器寄存器?”有可能。
“堆?”不。堆仅在显式调用 malloc 或等效函数时使用。没有已知的 C 编译器隐式使用堆。

Unfortunately I don't have enough asm / disasm skills to check it directly

您不需要了解很多汇编程序就可以做到这一点。只需将您的代码放入 https://godbolt.org/,禁用优化,这就是您得到的 (x86):

    mov     esi, 992
    mov     edi, 17
    call    sum_a_b
    mov     esi, eax
    mov     edi, 116
    call    mul_c_d

现在我们唯一需要知道的汇编程序是像mov这样的指令将结果存储在左操作数中。这就是为什么 memcpystrcpy 等 C 函数也将其结果存储在左操作数中的基本原理。

那么我们要知道esi,edi,eax是x86上的寄存器。所以它将 992 和 17 存储在寄存器中,然后调用该函数。之后,它会从第三个寄存器 eax 中取出一些东西并将它放在 esi 中。因此 sum_a_b 中的 return 值存储在 eax 中。

现在,如果我启动优化,整个 mul_c_d 调用将被 mov eax, 117044 取代。因此,编译器不仅能够内联所有函数调用,还能够在编译时预先计算结果。所以我们可以看出,我们启用的优化越多,知道结果存储在哪里变得越来越无关紧要。

Where can I read about this?

所有汇编器都有些相似,因此通过学习任何汇编器的基础知识,您可以大致了解它们的工作原理。当您学习汇编程序时,您将了解函数调用约定如何“在引擎盖下”工作。一些资源可以在这里找到:https://whosebug.com/tags/assembly/info