【问题标题】:The call stack drawing调用栈图
【发布时间】:2020-10-25 10:08:32
【问题描述】:
   void main() {
           int a = 10;
           int b = 37;
           swap(&a, &b);
           cout << "a = " << a << endl;
           cout << "b = " << b << endl;
    }
    void swap (int* a, int *b) {
            int temp = *a;
            *a = *b;
            *b = temp;
    }

您好,我有一个这样的程序。 我想画一张详细描述调用堆栈的图片,但我不知道我是否理解正确。 给我建议,如果我错了你能改正吗?

| local of spam() *b=temp       |
| local of spam() *a=*b         |
| local of spam() <int> temp=*a |
| Local variables adress of a, b| // example  0x100 a , 0x102 b
| return adress of swap()       |
| call Swap                     |
| Parameter a,b                 |
| Local variables a =10 ,b = 37 |

 

【问题讨论】:

  • 你好像有些误会。你读过哪些文学作品?为什么你认为语句本身是调用堆栈的一部分?

标签: c++ callstack


【解决方案1】:

您的总体思路是正确的,但细节取决于实现——它们并未在 C++ 标准本身中指定,它们也可能因编译器优化设置而异。您期望在堆栈上的许多东西可能只是放在 CPU 寄存器中(实际上编译器使用的调用约定可能要求它通过寄存器将某些参数传递给函数,而其他参数则通过堆栈传递)。只有数据进入堆栈,而不是操作。

不过,正如我所说,您通常可以很好地想象它,以用于高级编程的一般心理模型。您的模型中不太正确的是:

  • "return address of swap()" / "call Swap" -> 按时间顺序,调用函数中需要在被调用函数返回时执行的下一个地址通常保存在某处(堆栈或特定寄存器)在调用之前(如果没有 CPU call 指令,并且实际使用了 jump 指令时尤其常见),或者由 CPU 的调用指令本身进行

    • 因此,以相反的顺序列出它们会更准确,或者完全省略 call Swap
  • 在调用之前或调用时可能还有其他 CPU 寄存器要保留,或者在某些 CPU 上存在 CPU 寄存器的“窗口”,调用在调用时移入和移出并返回;许多细微的变化,但对于您作为 C++ 程序员的高级理解并不重要

  • "local of spam() *a=*b" / "local of spam() *b=temp" 不会有与那里的赋值相关的堆栈使用;您已经提到地址可以通过“Local variables adress of a, b”中的堆栈传递

(如果您想要更深入的了解,请使用 gdb 之类的调试器来检查整个程序执行过程中的堆栈)。

【讨论】:

    猜你喜欢
    • 2018-06-30
    • 2012-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 2011-04-17
    相关资源
    最近更新 更多