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 小得多。
在 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 小得多。