我试图在NASM / x86程序集中使用sys_brk分配一些内存。 sys_break返回break的新地址,这是数据段的结尾对吗?那么我新分配的内存在哪里?我假设它介于旧的中断值和新的中断值之间。因此,如果我使用sys_brk分配64字节的内存,我可以使用接下来的64个字节,从我在调用sys_brk之前存储的旧中断值开始。我是对的吗?
我将分配内存的汇编代码看起来有点像这样。https://gist.github.com/nikAizuddin/f4132721126257ec4345
另一个问题是;
我应该在Assembly中编写一个函数,它返回指向动态分配的内存的指针,该函数将从C程序中调用。如何从程序的C端释放这块内存?只是调用free()就够了吗?
答案 0 :(得分:0)
brk(2)
手册页(部分:C库/内核ABI差异)描述了如何在Linux的系统调用之上实现glibc包装器,该系统调用在成功时返回新的brk,或者在失败时返回旧的brk。
据我了解,超出当前中断的内存未映射。当前中断下方的地址是数据段的一部分(在数据+ bss +堆的意义上)。关于中断是否必须是页面对齐的文档并不清楚。 (即你可以sbrk(64),还是仅仅sbrk(4096)?)
请参阅:What does brk( ) system call do?该问题的答案为an example of using sbrk to replace malloc for code-golf。所以是的,旧的休息是要返回的地址。显然你可以sbrk
增加你想要的任何增量,而不仅仅是页面。
你是编写内存分配器的人。 sbrk
只是让您从操作系统中获得更多信息,例如mmap(MAP_ANONYMOUS)
,但不太灵活。 它无法帮助您跟踪空闲块,因此您可以将它们用于将来的分配,而不是总是从操作系统获得更多。
使用sbrk
回馈内存的方法是使用负参数调用sbrk
。显然这需要一个后进先出的使用模式,这就是为什么glibc的malloc只使用sbrk
进行小分配(可以在释放时放在空闲列表中,为将来的mallocs分发) 。大分配最好立即返回操作系统,而不是保持映射,因此glibc的malloc使用mmap
。
永远不要在free(3)
(或malloc(3)
之类的相关功能(或strdup(3)
)上找到的内存上free(3)
,您可以在文档中说明munmap
increment = 0
如果你在程序中断以下的内存页面上调用malloc(3)
会发生什么情况。可能它只会起作用,但是如果中断减少到那里你会在数据段中保留可能会导致问题。
获取当前brk的最简单方法是简单地使用$ strace -e brk ls 2>&1 | m
brk(0) = 0x650000
brk(0) = 0x650000
brk(0x671000) = 0x671000
调用它。
这就是glibc的end(3)
内部所做的事情:
&end
brk手册页提到了#app/models/order.rb
class Order < ActiveRecord::Base
def not_liked user, from_id
joins(:likes).where(status: "pending", id > from_id).not(likes: {user_id: user.id})
end
end
。显然,有一些全局变量位于文本,数据和bss段的末尾。但是,@order = Order.not_liked current_user, "5"
只是“程序中断附近”,这就是为什么malloc仍然必须调用sbrk(0)来获得初始中断。