Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory management 数据段对进程的堆栈分配及其占用_Memory Management_Process_Operating System - Fatal编程技术网

Memory management 数据段对进程的堆栈分配及其占用

Memory management 数据段对进程的堆栈分配及其占用,memory-management,process,operating-system,Memory Management,Process,Operating System,抱歉,如果这些问题是愚蠢的,但它们真的让我困惑! 根据elf标准,二进制文件分为文本段(包含代码和RO数据)和数据段(包含RW和BSS),当程序执行和进程创建时,数据段加载到内存中,这些段为进程执行的环境准备提供信息。 问题是,当我在进程创建过程中不提供堆栈大小时,如何确定要分配给进程的堆栈数量? 此外,使用数据段,我们可以确定进程需要多少内存(对于全局变量),但一旦分配了内存,如何使用分配内存中的地址空间进行变量映射? 最后,这与分散载荷有关系吗?我认为情况并非如此,因为在将图像加载到内存中时

抱歉,如果这些问题是愚蠢的,但它们真的让我困惑! 根据elf标准,二进制文件分为文本段(包含代码和RO数据)和数据段(包含RW和BSS),当程序执行和进程创建时,数据段加载到内存中,这些段为进程执行的环境准备提供信息。 问题是,当我在进程创建过程中不提供堆栈大小时,如何确定要分配给进程的堆栈数量? 此外,使用数据段,我们可以确定进程需要多少内存(对于全局变量),但一旦分配了内存,如何使用分配内存中的地址空间进行变量映射? 最后,这与分散载荷有关系吗?我认为情况并非如此,因为在将图像加载到内存中时,分散加载是完成的,一旦控制传递给操作系统,分配给可执行文件或应用程序的内存将由操作系统自己处理! 我知道这些问题太多了,但我们将非常感谢您的帮助。 如果你能提供任何参考书或链接,我可以在其中详细研究这一点,这也是感谢。
谢谢你一吨!:)

问题是,当我在进程创建过程中不提供堆栈大小时,如何确定要分配给进程的堆栈数量?

创建新进程时,
execve()
系统调用用于将新程序作为进程映像从当前运行的进程映像加载到内存中。这意味着当加载新程序时,将替换旧的
.text
.data
段,
并重置
堆栈
。现在ELF可执行文件被映射到内存地址空间,使堆栈空间通过环境数组和参数数组初始化为
main()

子例程()下的In()过程调用处理以下任务:

  • 使用调用()管理进程地址空间的
    mm_struct
    的新实例

  • 使用()初始化此实例

  • ()初始化堆栈

  • ()例行程序搜索合适的,即分别加载程序或动态库的load_binaryload_shlib。然后将内存映射到虚拟地址空间,并在调度器识别进程时使进程准备好运行

    所以,堆栈内存最终如下所示,它将在执行开始时出现在
    main()
    例程中。函数调用子集的每个环境,包括参数和局部变量,在调用发生时都会动态地存储或推送到堆栈内存区

    -----------------
    |                 | <--- Top of the Stack
    | environmental   | 
    | variables and   |
    | the other       |
    | parameters to   |
    | main()          |
     _________________  <--- Stack Pointer
    |                 |                
    |  Stack Space    |
    |                 |   
    
    使用
    readelf
    显示
    .data
    节头,如下所示

        $readelf -a elf
        ...
        Section Headers:
        [26] .data             PROGBITS         00000000006c2060  000c2060
           00000000000016b0  0000000000000000  WA       0     0     32
        [27] .bss              NOBITS           00000000006c3720  000c3710
           0000000000002bc8  0000000000000000  WA       0     0     32
        ...
        $readelf -x 26 elf
        Hex dump of section '.data':
        0x006c2060 00000000 00000000 00000000 00000000 ................
        0x006c2070 0a000000 00000000 00000000 00000000 ................
        ...
    
    让我们使用GDB来查看这些部分包含的内容

       (gdb) disassemble 0x006c2060
       Dump of assembler code for function `data_start`:
       0x00000000006c2060 <+0>: add    %al,(%rax)
       0x00000000006c2062 <+2>: add    %al,(%rax)
       0x00000000006c2064 <+4>: add    %al,(%rax)
       0x00000000006c2066 <+6>: add    %al,(%rax)
       End of assembler dump.
    
    上述反汇编转储全局变量
    value1
    的地址,初始化为 10但在接下来的地址中,我们看不到全局未初始化变量
    value2

    让我们看看打印
    value2
    的地址

       (gdb) p &value2 
       $1 = (int *) 0x6c5eb0
       (gdb) info symbol 0x6c5eb0
       value2 in section **.bss**
       (gdb) disassemble 0x6c5eb0 
       Dump of assembler code for function `value2`:
       0x00000000006c5eb0 <+0>: add    %al,(%rax)
       0x00000000006c5eb2 <+2>: add    %al,(%rax)
       End of assembler dump.
    
    (gdb)p&value2
    $1=(整数*)0x6c5eb0
    (gdb)信息符号0x6c5eb0
    第**.bss节中的值2**
    (gdb)拆解0x6c5eb0
    函数“value2”的汇编程序代码转储:
    0x00000000006c5eb0:添加%al,(%rax)
    0x00000000006c5eb2:添加%al,(%rax)
    汇编程序转储结束。
    
    塔达!分解
    value2
    的引用指针表明变量存储在
    .bss
    节中。这解释了未初始化的全局变量如何映射到进程内存空间

    最后,这与分散负载有关系吗

    没有

       (gdb) disassemble 0x006c2070
       Dump of assembler code for function `value1`:
       0x00000000006c2070 <+0>: or     (%rax),%al
       0x00000000006c2072 <+2>: add    %al,(%rax) 
       End of assembler dump.
       ....
    
       (gdb) p &value2 
       $1 = (int *) 0x6c5eb0
       (gdb) info symbol 0x6c5eb0
       value2 in section **.bss**
       (gdb) disassemble 0x6c5eb0 
       Dump of assembler code for function `value2`:
       0x00000000006c5eb0 <+0>: add    %al,(%rax)
       0x00000000006c5eb2 <+2>: add    %al,(%rax)
       End of assembler dump.