在Linux(x86)上-尽管您的进程具有4GB的虚拟地址范围,但并非所有内容都可以访问。最高的1GB是内核所在的位置,还有一些无法使用的低内存区域。默认情况下,无法写入或读取虚拟内存地址0xfff(by default),因此您的程序会崩溃,并出现段错误。
在您的后续评论中,您提到您打算使用汇编语言创建堆。这是可行的,其中一种方法是使用
sys_brk 系统调用。通过
int 0x80
和
EAX=45 访问它。它接受
EBX 中表示堆顶的指针。通常来说,堆区域底部被初始化为刚超过程序数据段(在内存中位于程序之上)的区域。要获取初始堆位置的地址,可以将
EBX 设置为 0 调用
sys_break。系统调用后,
EAX 将是堆的当前基指针。当您需要访问堆内存或分配更多堆空间时,您可以保存它。
以下代码提供了一个示例,以便更清晰地理解(而非性能),但可能是理解如何操作堆区域的起点:
SECTION .data
heap_base: dd 0
SECTION .text
global _start
_start:
mov eax, 45
xor ebx, ebx
int 0x80
mov [heap_base], eax
mov eax, 45
mov ebx, [heap_base]
add ebx, 0x2000
int 0x80
mov eax, [heap_base]
mov dword [eax+0xFFF], 25
mov eax, 1
xor ebx, ebx
int 0x80
ebx
写入0xFFC
或0x1000
,但不能写入中间的任何地址。 - Weather Vane