gpt4 book ai didi

c - X86 中的 C 函数需要多少堆栈和堆(以字节为单位)

转载 作者:行者123 更新时间:2023-11-30 20:09:03 25 4
gpt4 key购买 nike

“C”中函数 sum 的实现如下:

int sum(int b[], int c)
{
int s,i;

if (c<0)
{
printf("ERROR\n");
}
s = 0;

for(i=0; i<c; ++i)
{
s = s + b[i];
}
return s;
}

我想知道,X86 Linux 平台上的函数 sum 需要多少堆栈和堆(以字节为单位)?如何知道这一点?

从中断处理程序中调用该函数是否可能出现问题或成功?

最佳答案

为了以其他用户已经指出的内容为基础,我将尝试解决OP的这两个问题。

OP的第一个问题:

I'd like to know, How much stack and heap in bytes is required by the function sum in X86 Linux platform? How to know this?

我们可以将第一个问题分为两部分。一个是关于堆栈大小,另一个是关于堆大小。

堆栈大小:

要了解您的函数使用了多少堆栈,您可以使用 GCC 诊断编译指示之一,即 -Wframe-larger-than=<X>杂注。这是一个关于如何使用它的示例。首先,我们将编译指示添加到代码中并保存文件。

main.cpp

#include <stdio.h>
#pragma GCC diagnostic error "-Wframe-larger-than=1"

int sum(int b[], int c) {
int s,i;
if (c<0) {
printf("ERROR\n");
}
s = 0;
for(i=0; i<c; ++i) {
s = s + b[i];
}
return s;
}

我们现在可以尝试编译代码:

junglefox@ubuntu:~$ gcc -c main.cpp
main.cpp: In function ‘int sum(int*, int)’:
main.cpp:20:1: error: the frame size of 32 bytes is larger than 1 bytes [-Werror=frame-larger-than=]
}
^
cc1plus: some warnings being treated as errors
junglefox@ubuntu:~$

报告的大小为32 字节

  • 测量堆栈大小的另一种方法是使用 stack-usage GCC 中的编译器标志。因此,我们删除或注释掉 // #pragma GCC diagnostic error "-Wframe-larger-than=1"行并尝试再次编译该文件,如下所示。

junglefox@ubuntu:~$ gcc -c main.cpp -fstack-usage

这将生成一个文件main.su .

junglefox@ubuntu:~$ cat main.su 
main.cpp:5:5:int sum(int*, int) 48 static

这显然表明我们正在使用 48 字节 的堆栈。

<小时/>

堆大小

要了解我们的程序使用了多少堆大小,我们将使用 valgrind工具Massif 。为此,我们首先需要在代码中添加一个 main() 函数(没有它我们无法创建二进制文件。而二进制文件就是我们需要使用 valgrind 运行的)。所以main.cpp ,现在看起来像这样,

#include <stdio.h>
// #pragma GCC diagnostic error "-Wframe-larger-than=1"

int sum(int b[], int c) {
int s,i;
if (c<0) {
printf("ERROR\n");
}
s = 0;
for(i=0; i<c; ++i) {
s = s + b[i];
}
return s;
}

int main() {
// As Peter pointed, uncomment one of the following lines,
// for it to be a valid test. Also, compiler optimizations,
// when turned on, can give different results.
// sum(NULL,0);
// sum(NULL,-1);
return 0;
}

现在我们将在 valgrind 的帮助下编译、构建和运行二进制文件,如下所示:

junglefox@ubuntu:~$ gcc -o main main.cpp
junglefox@ubuntu:~$ valgrind ./main --tool=massif

这将生成一堆信息,如下所示:

    ==8179== Memcheck, a memory error detector
==8179== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8179== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==8179== Command: ./main --tool=massif
==8179==
==8179==
==8179== HEAP SUMMARY:
==8179== in use at exit: 0 bytes in 0 blocks
==8179== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==8179==
==8179== All heap blocks were freed -- no leaks are possible
==8179==
==8179== For counts of detected and suppressed errors, rerun with: -v
==8179== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

报告堆使用总量为 0 KB。

此外,正如 @mevets 试图解释的那样,您始终可以查看编译器生成的底层汇编代码。在海湾合作委员会,你可以这样做,

junglefox@ubuntu:~/gcc -S main.cpp
junglefox@ubuntu:~/cat main.s

这将向您展示您的函数在底层汇编输出中的样子。

注意/编辑:但为了完整起见,在 C 或 C++ 中,没有使用 malloc() 进行动态内存分配。或new ,作为程序员,您没有使用堆。另外,除非您在函数内声明数组,否则您不会使用任何大量的堆栈。

<小时/>

OP的第二个问题:

Is invocation of the function from within an interrupt-handler likely to be problematic or successful?

正如许多人在评论中善意指出的那样,请勿使用 printf()在您的中断处理程序中。

引用此link :

What differentiates interrupt handlers from other kernel functions is that the kernel invokes them in response to interrupts and that they run in a special context called interrupt context. This special context is occasionally called atomic context because code executing in this context is unable to block.

Because an interrupt can occur at any time, an interrupt handler can be executed at any time. It is imperative that the handler runs quickly, to resume execution of the interrupted code as soon as possible.

所以,除了 printf() ,可能需要很长时间的一件事是,当用作 Interrupt Service Routine 时,传递给该函数的数组有多大。 。它的复杂度为O(n) 。如果c太大,您的程序将暂停相对较长的时间,直到 ISR 完成 for()循环。

关于c - X86 中的 C 函数需要多少堆栈和堆(以字节为单位),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54001978/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com