Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.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
Operating system 在C语言中包含一个库,它放在地址空间的什么位置?_Operating System_Shared Libraries_Address Space - Fatal编程技术网

Operating system 在C语言中包含一个库,它放在地址空间的什么位置?

Operating system 在C语言中包含一个库,它放在地址空间的什么位置?,operating-system,shared-libraries,address-space,Operating System,Shared Libraries,Address Space,我理解地址空间是如何划分为代码、数据、堆栈和堆的。然而,对于给定的C代码,我很难将什么映射到何处 我知道: 全局变量位于数据部分。静态变量位于数据部分。局部变量位于堆栈部分。动态分配的空间位于堆部分。 我的问题是,当把一个库包含到一个程序中时,它放在地址空间的什么位置 我希望这个问题有意义。实际上,如果您有基于linux的pc,您可以通过以下方式自己检查: 创建一个简单的c应用程序,在main()中使用无限while循环 编撰 $gcc-o main./main.c-g 发射 $gdb./mai

我理解地址空间是如何划分为代码、数据、堆栈和堆的。然而,对于给定的C代码,我很难将什么映射到何处

我知道: 全局变量位于数据部分。静态变量位于数据部分。局部变量位于堆栈部分。动态分配的空间位于堆部分。 我的问题是,当把一个库包含到一个程序中时,它放在地址空间的什么位置


我希望这个问题有意义。

实际上,如果您有基于linux的pc,您可以通过以下方式自己检查:

  • 创建一个简单的c应用程序,在main()中使用无限while循环
  • 编撰

    $gcc-o main./main.c-g

  • 发射

    $gdb./main

  • 显示映射信息

    (gdb)r

    (gdb)信息过程映射

    映射地址空间:

          Start Addr           End Addr       Size     Offset objfile
            0x400000           0x401000     0x1000        0x0 /tmp/main
            0x600000           0x601000     0x1000        0x0 /tmp/main
            0x601000           0x602000     0x1000     0x1000 /tmp/main
            0x602000           0x623000    0x21000        0x0 [heap]
      0x7ffff7a0d000     0x7ffff7bcd000   0x1c0000        0x0 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff7bcd000     0x7ffff7dcd000   0x200000   0x1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff7dcd000     0x7ffff7dd1000     0x4000   0x1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff7dd1000     0x7ffff7dd3000     0x2000   0x1c4000 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff7dd3000     0x7ffff7dd7000     0x4000        0x0
      0x7ffff7dd7000     0x7ffff7dfd000    0x26000        0x0 /lib/x86_64-linux-gnu/ld-2.23.so
      0x7ffff7fd4000     0x7ffff7fd7000     0x3000        0x0
      0x7ffff7ff6000     0x7ffff7ff8000     0x2000        0x0
      0x7ffff7ff8000     0x7ffff7ffa000     0x2000        0x0 [vvar]
      0x7ffff7ffa000     0x7ffff7ffc000     0x2000        0x0 [vdso]
      0x7ffff7ffc000     0x7ffff7ffd000     0x1000    0x25000 /lib/x86_64-linux-gnu/ld-2.23.so
      0x7ffff7ffd000     0x7ffff7ffe000     0x1000    0x26000 /lib/x86_64-linux-gnu/ld-2.23.so
      0x7ffff7ffe000     0x7ffff7fff000     0x1000        0x0
      0x7ffffffdd000     0x7ffffffff000    0x22000        0x0 [stack]
    
  • 我们看到,这将c库放置在地址
    0x7ffff7bcd000-0x7ffff7dd5000
    中。偏移量字段-是ELF文件本身中的偏移量。我们可以使用readelf检查哪些部分对应于哪个偏移:

    $ readelf -a /lib/x86_64-linux-gnu/libc-2.23.so | less
    
    例如:

     [13] .text             PROGBITS         000000000001f8b0  0001f8b0
           0000000000153214  0000000000000000  AX       0     0     16
    

    这意味着
    .text
    部分具有偏移量
    0x1F800
    。从上面的映射中,我们可以得出结论:主应用程序地址空间中.text部分开头的虚拟地址将是
    0x7ffff7bcd000+0x1f8b0

    您是从一个不好的前提开始的:

    我理解地址空间是如何划分为代码、数据、堆栈和堆的。然而,对于给定的C代码,我很难将什么映射到何处

    地址空间不是以这种方式分区的。地址空间包含内存。用于堆栈的内存与用于堆的内存无法区分。使堆栈成为堆栈的唯一原因是,它是使用堆栈指针在应用程序中分配的。使堆成为堆的唯一原因是应用程序中有一个堆管理器。您可以从堆中分配内存,并将其分配给硬件堆栈指针,您的内存既是堆又是堆栈

    这是另一个误解:

    我知道:全局变量在数据部分。静态变量位于数据部分。局部变量位于堆栈部分。动态分配的空间位于堆部分

    汇编程序、链接器和系统之间的区别。然而,rational汇编器允许用户定义自己的命名部分。在许多汇编程序中,我可以创建Bobs_Data_段、Freds_Data_段和Sams_Data_段,并将全局变量放入其中

    对于大多数(但不是所有)编译器,程序员无法控制如何创建节。不能保证编译器会将全局变量放在一个名为“data”的节中。事实上,全局变量和静态局部变量可以放在同一节中

    这样的“部分”通常只是链接器的输入。链接器将汇编程序和编译器定义的部分组合到具有公共访问属性的内存区域中。进入链接器的内容,例如,链接器中的“数据”部分,作为可执行文件中的指令,用于创建读/写页面

    我的问题是,当把一个库包含到一个程序中时,它放在地址空间的什么位置

    因此,现在你遇到了一个问题,即你如何努力学习事物是如何工作的。如果将进程地址空间视为内存,则可以在任何位置加载库。程序加载器读取可执行文件中的指令,并在地址空间中的任何可用位置创建具有正确属性(例如readonly/noexecute、read/write、readonly/execute)的页面

    如果将地址空间视为被划分为代码、数据等,则加载库会出现问题。这让我想知道为什么学校和书籍坚持使用这些荒谬的概念进行教学