【问题标题】:(N)ASM, ELF64 - .data and .bss order in memory(N)ASM、ELF64 - 内存中的 .data 和 .bss 顺序
【发布时间】:2018-07-03 16:59:51
【问题描述】:

我有一个关于 .data 和 .bss 部分在内存中的顺序的问题, 我一辈子都无法用谷歌搜索它。

我试图了解是否可以保证 .bss 部分在内存地址方面总是在 .data 部分之后。

我的具体需求是这样的:

section .data
malloc_pointer:
    dq start_of_my_malloc

start_of_data:
; more stuff...

section .bss
; more stuff
start_of_my_malloc:
    resb 1 << 30 ; pre-allocate 1gig

而且我有时需要使用偏移量[malloc_pointer] - start_of_data,所以我需要它是正数,因此是关于 .bss 和 .data 顺序的问题。


作为一个方面 - 很高兴知道我是否可以引用标签 start_of_data 来帮助我选择要在 start_of_my_malloc 中保留的尺寸。 我真正想做的是:

start_of_my_malloc:
    resb (1 << 30) - start_of_data ; this won't compile though

谢谢!

【问题讨论】:

  • 我认为不能保证,取决于您的链接器脚本。
  • 为什么需要 offset 为正数?

标签: assembly nasm elf memory-layout


【解决方案1】:

关于节定位的决定由链接器完成,可以通过linker scripts(默认或自定义)进行控制。我会尽量不依赖它们,因为它们会使您的代码不那么独立。

关于你的第二个问题 - 你可以组装一次文件,从目标文件中提取 .data 的大小,然后用适当的 -DSTART_OF_DATA=... 重新组装它。

【讨论】:

    【解决方案2】:

    传统上,内存布局是首先出现文本,然后是数据,最后是 bss。这种设计很方便,因为您可以简单地将整个二进制文件复制到内存中,然后将一块内存归零,然后(可选)设置内存保护。要扩展 bss 段,可以使用brk 和sbrk 系统调用。

    三个标签etext、edata和end由链接器定义,指向文本段的结尾、初始化数据的结尾和数据段的结尾。不存在标签start,因为该程序传统上映射到地址0,因此不需要标签。

    不能保证布局是这样的,但是由于很多程序都依赖这种设计,所以在不久的将来不太可能改变。

    如果你想写一个内存分配例程,我推荐你使用sbrk系统调用。这消除了对布局假设的全部需求,因为sbrk 总是做正确的事情。

    注意sbrk今天有点过时了,所以如果你想使用现代的东西,我建议你在mmap之上实现你的内存管理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-12
      • 1970-01-01
      • 2011-12-30
      • 2016-12-03
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      相关资源
      最近更新 更多