NASM 可以分配多少内存?

How much memory can NASM allocate?

在 64 位系统上 NASM 可以分配多少内存 (Windows 7)?看来 fasm 只能分配大约 1.5 GB 的内存,所以我正在寻找更强大的汇编程序。

我很难弄清楚在 assembly 时你可以做什么需要那么多内存。我只能假设您在代码中分配了大量初始化数据。

如果它只是在运行时需要的东西,您正在使用的 OS 应该提供某种形式的动态分配,这不会影响您的 code/data 大小。

一个例子是 Windows HeapAlloc 函数,你只需要确保在从程序集调用它时遵循调用约定。

NASM 在 BSS 中处理巨大的数组没有问题。 (零初始化而不在可执行文件本身中使用 space)。

对于一个小程序来说,动态分配并不比静态分配好,但请记住,除非你把这个数组放在 BSS 的 end,否则你不会能够对最终位于其之上的其他变量进行 RIP 相对寻址;它们与您的代码相差超过 +-2GiB。

认为 BSS仍然可以在Linux上使用t运行sparent hugepages以同样的方式动态分配(mmap / VirtualAlloc) 可以,但这是需要仔细检查的事情。对于巨大的阵列,您肯定想要它。

将数组的基址置于静态已知地址可能会略微提高效率,允许像 [array + rdi] 这样的寻址模式而不是 [rsi + rdi] 占用另一个寄存器和索引寻址在某些情况下,模式会在 Sandybridge 系列上击败微融合(包括几乎所有可以首先微融合负载的 AVX ALU + 加载指令,Haswell/Skylake。)Micro fusion and addressing modes


这似乎是我最近 运行 关注的 FASM 的一个问题(可能是在查看您之前的一个问题时)。似乎 x86-64 Linux FASM 坚持根据 strace 输出使用 mmap(MAP_32BIT),是的,当尝试使用超过 1GiB 时它似乎失败了。

并且 FASM 想要将可执行布局映射到内存(?),包括 BSS,因此无法使用大于 assemble 时间虚拟地址的数组 space.


  lea  rdi, [rel big]
  mov eax, 231 
  syscall                 ; exit_group(low byte of address)

section .bss
big: resb 1024*1024*1024*40      ; 40GiB

NASM + ld assemble 这对 GNU/Linux 毫无怨言。但是 readelf -a 在生成的静态可执行文件上说 BSS 的 "memsiz" 只是“0x0000000100000000” (4GiB) 而不是 40GiB。

这可能是 NASM 的错:readelf -a 在 NASM 制作的 .o 上显示

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
    ...
  [ 6] .bss              NOBITS           0000000000000000  00000000
       00000000ffffffff  0000000000000000  WA       0     0     4
    ...

BSS 大小为 UINT32_MAX;比 40GiB 小得多。