NASM可以分配多少内存?

时间:2019-11-16 09:30:41

标签: assembly x86-64 nasm

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

2 个答案:

答案 0 :(得分:4)

我很难弄清楚该怎么做,那在组装时需要那么多的内存。我只能假设您在代码中分配了大量的初始化数据。

如果仅在运行时需要,则您所使用的操作系统应提供某种形式的动态分配,这不会影响您的代码/数据大小。

一个示例是Windows HeapAlloc函数,您只需要确保从程序集调用它时遵循调用约定即可。

答案 1 :(得分:2)

NASM对BSS中的巨大阵列没有任何问题。 (零初始化,不占用可执行文件本身的空间。)

对于小型程序,

动态分配并不比静态分配好,但是请记住,除非将该数组放在BSS的 end 处,否则您将无法进行RIP-结束于其上方的其他变量的相对寻址;它们将比您的代码多出+ -2GiB。

认为 BSS仍然可以在Linux上使用透明大页面,就像动态分配(mmap / VirtualAlloc)一样,但这需要仔细检查。您绝对想要大型阵列。

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


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

FASM希望将可执行程序布局映射到包括BSS在内的内存(?)中,从而无法使用大于汇编时间虚拟地址空间的数组。


  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在GNU / Linux上毫无抱怨地进行了组装。但是在生成的静态可执行文件上,readelf -a表示BSS的“ memsiz”仅为“ 0x0000000100000000”(4GiB),而不是40GiB。

这可能是NASM的错误:NASM节目制作的readelf -a上的.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小得多。