标签: callstack

x86 处理器可以调用多少个子例程?

我正在编写一个小程序,用 printf("\219") 打印一个多边形,看看我正在做的事情是否适合我的内核。但它需要调用很多函数,我不知道x86处理器是否可以接受那么多子例程,而且我在google中找不到结果。所以我的问题是它是否会接受这么多函数调用以及最大值是多少。(我的意思是这样的:-)

function a() {b();}
function b() {c();}
function c() {d();}
...
Run Code Online (Sandbox Code Playgroud)

我已经使用了 5 个这样的级别(你知道我的意思,对吧?)

c++ stack-overflow x86 gcc callstack

0
推荐指数
1
解决办法
357
查看次数

分配了多少内存给调用堆栈?

以前我见过很多C++函数的汇编。在 gcc 中,所有指令都以以下指令开头:

push    rbp
mov     rbp, rsp
sub     rsp, <X>  ; <X> is size of frame
Run Code Online (Sandbox Code Playgroud)

我知道这些指令存储前一个函数的帧指针,然后为当前函数设置一个帧。但在这里,程序集既不要求映射内存(如 malloc),也不检查所指向的内存是否rbp分配给进程。

因此它假设启动代码已经为调用堆栈的整个深度映射了足够的内存。那么到底为调用堆栈分配了多少内存呢?启动代码如何知道调用栈的最大深度?

这也意味着,我可以远距离访问越界数组,因为虽然它不在当前帧中,但它映射到进程。所以我写了这段代码:

int main() {
    int arr[3] = {};
    printf("%d", arr[900]);
}
Run Code Online (Sandbox Code Playgroud)

当索引为 900 时,它会退出。SIGSEGV但令人惊讶的是,当索引为 901 时,它不会退出。同样,SIGSEGV对于某些随机索引,它会退出,而对于某些索引则不会。在编译器资源管理器中使用 gcc-x86-64-11.2 进行编译时观察到此行为。

c++ callstack memory-management segmentation-fault

0
推荐指数
1
解决办法
741
查看次数

javascript中的async是并发还是并行?

JavaScript 代码在单线程上运行,在事件循环中,当方法推送到 Web api 时,将回调函数返回到队列,侦听器队列和调用堆栈为空推送回调函数在调用堆栈中执行它,因此异步执行实际上只是更改了功能?为什么?

javascript concurrency callstack asynchronous event-loop

0
推荐指数
1
解决办法
1597
查看次数

Scala3中如何进行尾调用优化?

我正在尝试编写一个 100% 迭代的程序,也就是说,函数永远不需要返回,因为在这样的返回之后不会发生任何事情。

换句话说,程序100%处于尾部位置。考虑以下玩具程序:

  def foo(): Unit =
    bar()

  def bar(): Unit =
    foo()

  try
    foo()
  catch
    case s: StackOverflowError =>
      println(" Stack overflow!")
Run Code Online (Sandbox Code Playgroud)

调用 foo 确实会导致堆栈溢出,这并不奇怪,事实上 foo 调用 bar,因为这样 bar 需要堆栈帧,bar 然后调用 foo,后者需要堆栈帧,等等。很明显为什么会发生堆栈溢出错误。

我的问题是,如何按原样定义 foo 和 bar 而不会出现堆栈溢出?像Scheme这样的语言允许这个程序,它们会永远运行,是的,但是堆栈不会增长,因为它知道调用后不需要发生任何事情,例如,来自foo的bar,所以不需要保留foo的堆栈帧呼叫酒吧。显然,scala(即 JVM?)确实使堆栈帧保持活动状态。

现在考虑下一个代码示例:

  def foo(): Unit = 
    foo()

  foo()
Run Code Online (Sandbox Code Playgroud)

该程序将永远运行,但永远不会发生堆栈溢出。

我知道 @tailrec 注释,但据我了解,它仅适用于第二个示例之类的情况,但不适用于第一个示例。

有任何想法吗?(我需要第一个示例像第二个示例一样永远运行,而不会出现堆栈溢出。)

recursion callstack scala tail-call-optimization stack-frame

0
推荐指数
1
解决办法
92
查看次数

为什么 GCC 为 C 数组分配太多堆栈空间

考虑以下程序:

int main()
{
   int arr[8];
}
Run Code Online (Sandbox Code Playgroud)

在 linux 20 上使用 gcc 9.3.0 编译时,文件的反汇编一开始看起来像这样(这不是上面代码的整个汇编!):

? 72: int dbg.main (int argc, char **argv, char **envp);
?           ; var int[8] arr @ rbp-0x30
?           ; var int64_t canary @ rbp-0x8
?           0x00001169      f30f1efa       endbr64                     ; test.c:2 { ; int main();
?           0x0000116d      55             push rbp
?           0x0000116e      4889e5         mov rbp, rsp
?           0x00001171      4883ec30       sub rsp, 0x30
Run Code Online (Sandbox Code Playgroud)

arr只有 8 个整数 = 8 * 4 个字节长 ( sub rsp, 0x30)时,为什么汇编程序在堆栈上分配 …

c assembly gcc callstack x86-64

-1
推荐指数
1
解决办法
112
查看次数

英特尔64位,奇怪的RSP行为

我遇到了使用IDA在Windows中调试64位二进制文​​件的问题.通常情况下,推送 RSP值应该扣除8.但偶尔,从IDA我看到RSP仅扣除2,然后是下一次推送8.

涉及的代码是

push rax
push rbx
push rsi
push rdi
Run Code Online (Sandbox Code Playgroud)

我对x64环境很新,因此任何人都可以解释这种行为吗?

assembly callstack x86-64 ida

-3
推荐指数
1
解决办法
67
查看次数