assembly - NASM 中的 .bss 部分中声明的变量是否会加载到进程的数据部分而不是进程的 bss 部分?

标签 assembly x86 nasm

我使用 NASM 组装了以下代码:

global _start

section .data
    var1 DD 0xA1A2A3A4        ; 4 bytes
    var2 DD 0xB1B2B3B4        ; 4 bytes
section .bss
    var3: RESD 1              ; 4 bytes

section .text
_start:
    mov DWORD [var3], 0xC1C2C3C4

我在 OllyDbg 中打开文件并使其执行指令:mov DWORD [var3], 0xC1C2C3C4 .

这是执行该指令后 OllyDbg 左下 Pane 的状态以及内存映射:

enter image description here

如您所见,数据部分从地址 0x00F02000 开始,大小为 0x1000 字节(因此 var3 是数据部分的一部分)。

<小时/>

编辑:

我使用以下命令创建了目标文件:

nasm -f win32 D:\1.asm

为了创建 EXE 文件,我使用 Visual C++ 2010 链接器使用以下命令:

link D:\1.obj /OUT:D:\1.exe /ENTRY:start /SUBSYSTEM:CONSOLE

最佳答案

这是由 Microsoft 链接器执行的优化。

PE 格式规范要求为每个部分分配 VirtualSize 字节。 VirtualSize 通常为 4 KB,是 Windows 上文件对齐倍数和内存页的大小。由于您的 .data 部分小于 4 KB,因此之后可以轻松容纳未初始化的数据,从而占据“闲置”空间。

如果要引入单独的 .bss 部分,那么这将使二进制文件变得更大并增加加载时间,而没有任何令人信服的原因。链接器选择将 .data.bss 部分合并为一个。

这些附加数据(否则会进入 .bss 部分)不会增加 .data 部分的原始大小因为这些数据实际上不需要存储在二进制文件中的任何位置。因此,它与.bss本质上具有相同的效果。

Paweł Łukasik observed ,MinGW 的链接器不执行相同的优化。

Borland 的 TLINK(现在可能仅具有历史意义)从未发出 .bss 部分。它总是扩展 .data 部分的虚拟大小。

关于assembly - NASM 中的 .bss 部分中声明的变量是否会加载到进程的数据部分而不是进程的 bss 部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45029393/

相关文章:

linux - 如何将此 linux 汇编代码更改为兼容的 UNIX 汇编代码?

c++ - C++中的noexcept如何改变程序集?

c - %al 在 C 代码中注册

c++ - 如何将 C++ 子例程链接到 x86 汇编程序?

NASM x86 程序集中的 C float

pointers - 帮助破译几行 assembly 线

FXSAVE 能否在 FXRSTOR 之前执行两次?

c - x86 测试指令不起作用?

windows - call immediate 与 call dword near [dword addr]

assembly - 行首应有标签或说明