相关疑难解决方法(0)

callstack究竟是如何工作的?

我试图更深入地了解编程语言的低级操作是如何工作的,尤其是它们如何与OS/CPU交互.我可能已经在Stack Overflow上的每个堆栈/堆相关线程中阅读了每个答案,并且它们都很棒.但还有一件事我还没有完全理解.

在伪代码中考虑这个函数,这往往是有效的Rust代码;-)

fn foo() {
    let a = 1;
    let b = 2;
    let c = 3;
    let d = 4;

    // line X

    doSomething(a, b);
    doAnotherThing(c, d);
}
Run Code Online (Sandbox Code Playgroud)

这就是我假设堆栈在X行上的样子:

Stack

a +-------------+
  | 1           | 
b +-------------+     
  | 2           |  
c +-------------+
  | 3           | 
d +-------------+     
  | 4           | 
  +-------------+ 
Run Code Online (Sandbox Code Playgroud)

现在,我读到的关于堆栈如何工作的一切都是它严格遵守LIFO规则(后进先出).就像.NET,Java或任何其他编程语言中的堆栈数据类型一样.

但如果是这样,那么在X行之后会发生什么?显然,接下来我们需要的是使用ab,但这意味着操作系统/ CPU(?)必须弹出dc首先回到ab.但是它会在脚下射击,因为它需要c并且d在下一行.

所以,我想知道幕后究竟发生了什么?

另一个相关问题.考虑我们传递对其他函数的引用,如下所示:

fn foo() {
    let …
Run Code Online (Sandbox Code Playgroud)

cpu assembly callstack calling-convention low-level

99
推荐指数
5
解决办法
2万
查看次数

ARM:链接寄存器和帧指针

我试图理解链接寄存器和帧指针在ARM中是如何工作的.我去过几个网站,我想确认一下我的理解.

假设我有以下代码:

int foo(void)
{
    // ..
    bar();
    // (A)
    // ..
}

int bar(void)
{
    // (B)
    int b1;
    // ..
    // (C)
    baz();
    // (D)
}

int baz(void)
{
    // (E)
    int a;
    int b;
    // (F)
}
Run Code Online (Sandbox Code Playgroud)

我叫foo().将链接寄存器包含在点(A)的地址码和帧指针包含在代码点(B)的地址?在声明了所有本地人之后,堆栈指针可以是bar()内的任何位置吗?

[编辑]添加了另一个函数调用baz()

c arm

28
推荐指数
1
解决办法
5万
查看次数

捕获MinGW编译文件时,Very Sleepy看不到函数名称

我是新手,所以可能会遗漏一些基本的东西.我使用gcc 4.8(MinGW)和-g选项编译我的C程序.

然后我运行它并使用Very Sleepy捕获它.这一切都有效,但Sleepy的输出看起来像这样:

memcpy             0.98 0.98 7.65 7.65  msvcrt unknown 0
[00000000004038FE] 0.77 0.77 6.02 6.02  a              0
memset             0.63 0.63 4.92 4.93  msvcrt unknown 0
[0000000000404549] 0.42 0.42 3.29 3.29  a              0
[000000000040282A] 0.35 0.35 2.73 2.73  a              0
[0000000000404600] 0.25 0.25 1.99 1.99  a              0
....
etc.
Run Code Online (Sandbox Code Playgroud)

(我的应用程序叫做a.exe)
所以Sleepy看不到函数名,我怎么需要编译/运行才能使它工作?困倦的网站给出:

支持GCC/mingw.您现在可以使用嵌入的DWARF2数据分析可执行文件,它应该可以工作.此处不需要特殊选项,只需使用"-g"进行编译即可确保符号存在.您可能还希望使用"-fno-omit-frame-pointer"来确保正确的callstack,尽管Sleepy通常可以以任何方式工作.您不需要使用"-pg"或任何垃圾.它甚至可以在Microsoft DLL之间将正确的堆栈转换为GCC堆栈,这比你想象的要难.

但就我而言,这还不够.

windows gcc profiling verysleepy

13
推荐指数
1
解决办法
2384
查看次数