Linux中可用于汇编程序的内存

问题描述 投票:2回答:1

为了好玩,我只是尝试在装有x86处理器的笔记本电脑上为Linux编写汇编程序,以获取一些系统信息。所以我想找到的一件事是我的程序有多少可用内存,例如堆栈是,如果需要,以及如何以及如何分配额外的内存。

很久以前,我在Atari ST上做过这样的事情,只有一个系统'malloc',我可以从中询问内存,并且有一些函数来查找可用的内存。

我知道Linux的设置不同,我自己拥有整个地址空间,但是我想有些内存区域是我不允许接触的。

而且似乎已经设置了默认堆栈。

我对此进行了大量研究,但找不到任何“汇编”系统调用。大多数人都指向链接C malloc进行内存管理,但是我并不是在寻找内存管理器。我只想知道程序的内存边界。

我发现诸如getrlimit,setrlimit,prlimit和brk和sbrk之类的东西,但这些似乎是C函数,而不是系统调用。

我想念什么?

linux assembly system-calls
1个回答
1
投票

Linux使用虚拟内存(和ASLR)。 Atari ST均未使用任何一种,因此它为某些OS数据结构和代码提供了固定的内存映射。 (由于操作系统位于ROM中,并且无法轻松更新,因此有些人甚至记录了一些内部地址。)

Linux试图保持内核与用户空间之间的界限严格,使用定义明确的文档化API / ABI来使用户空间通过系统调用与内核进行交互。 (例如,通过syscall指令在x86-64上)。用户空间不需要关心那堵墙的另一侧,只要它有指向它们的指针,通常甚至不必关心其页面在虚拟内存中的位置。

[当glibc syscall要从操作系统中获取更多页面时,它使用mallocmmap(MAP_ANONYMOUS)来获取它们,并将其中的大块分发给对brk的小调用。它将簿记数据结构保留在用户空间中(因此,这当然是每个过程的结果。)>

我知道Linux的设置不同,我自己拥有整个地址空间,但是我想有些内存区域是我不允许接触的。

是的,每个进程都有其自己的虚拟地址空间。您只能触摸已分配的部分,否则导致的页面错误将是“无效的”(操作系统知道该虚拟页面不应该存在物理页面),并且如果您将SIGSEGV信号发送给您的过程,尝试读或写它。 (“有效”页面错误是由于交换空间或延迟分配/写时复制而发生的;内核更新硬件页面表并返回到用户空间以使其重新运行出现故障的指令。)

此外,内核要求虚拟地址空间的上半部分供自己使用。 (malloc)。另请参阅https://wiki.osdev.org/Higher_Half_Kernel以了解Linux的x86-64内存映射布局。

我找不到任何“程序集”系统调用。

https://www.kernel.org/doc/Documentation/x86/x86_64/mm.txtmmap是真实的系统调用。请参见brk的“注释”部分。第2节的手册页是系统调用,第3节是libc函数。

当然,在C中,当您调用brk(2) man page时,实际上是在glibc中调用包装函数。 glibc提供包装器功能,而不是直接使用brk(2)指令的内联asm宏。

另请参见mmap(...)

,其中说明了asm界面以及VDSO页面。 Linux将一些内核内存(只读)映射到您的用户空间进程中,以保存代码和数据,以便syscallThe Definitive Guide to Linux System Calls可以在用户空间中运行。

关于堆栈溢出的各种问答,包括getpid()


所以我要查找的东西之一是程序可以使用多少内存

没有系统调用来查询您的进程的当前内存映射。解析clock_gettime()是最好的选择。

有关使用系统调用扫描映射页面的虚拟地址空间范围的一些有趣想法,请参见What are the calling conventions for UNIX & Linux system calls on i386 and x86-64。例如就像Linux的/proc/self/maps如果指定范围包含任何未映射的页面,则返回Finding mapped memory from inside a process

© www.soinside.com 2019 - 2024. All rights reserved.