这段汇编代码的解释

3
void* curbrk;

__asm__ __volatile__(
    "mov .curbrk, %%rax;"
    "mov %%rax, %0"
        : "=r" (curbrk)
        :: "%rax"
);

有人能解释一下这个简单的汇编代码是做什么的吗?谢谢。


就目前而言,没有什么特别的。.curbrk 不是指寄存器、标签或其他有意义的符号。 - Michael Foukarakis
那么它是什么?这也是我无法弄清楚的。 - Raj
2个回答

5
它将符号.curbrk的值复制到C变量curbrk中,可能在汇编或链接器脚本中定义,在此过程中破坏了RAX寄存器。

.curbrk可能指向数据段的当前末尾。Glibc似乎定义了一个类似的符号__curbrk,您可能正在使用其他libc(BSD?)。无论如何,sbrk(0)是访问该值的更可移植的方式。

在查看了FreeBSD交叉引用之后,我可以说它确实指向数据段的当前末尾:它被brk()sbrk()两者使用,并使用HIDENAME宏来添加一个.,并且它出现在amd64的System.map中(在当前版本的FreeBSD上不再是这样)。
请注意,在较新的FreeBSD中,brk()sbrk()已被重新实现,不再依赖于.curbrk,它是从_end初始化的,后者应该来自可执行文件,但在混合LLVM的ld和GNU ld时会出现问题。因此,brk()sbrk()现在使用内核来初始化其内部的curbrk,不再依赖于_end。有关详细信息,请参见FreeBSD PR228754

是的,没错 :) 我正在使用FreeBSD。[我也认为.curbrk可能是一个编译器定义的变量,可能指向DS的末尾,试图搜索它,但找不到任何信息。] 那么如何使用brk(0)访问数据段的末尾 - brk不返回任何指针,而且brk(0)会将程序的数据段缩小到0。 - Raj
@Raj Kumar:抱歉,我是指sbrk(0) - ninjalj
@Raj:此外,DS可能与此无关。 DS和其他选择器可能设置为提供平面地址空间,并通过分页实施限制,这在*nix中是传统的做法。 - ninjalj
是的,sbrk(0)可以用于访问当前系统断点。但我发布的代码实际上是我自己尝试实现的sbrk代码。(因此,在sbrk中调用sbrk(0)将是无意义的)。我正在寻找其他方法来实现这一点。 - Raj
我猜当你说“它复制了符号.value的值”时,你是指.curbrk - Michael Petch
@MichaelPetch:我不知道9年前我在想什么,但我猜是这样。趁机更新了链接,并对当前的变化添加了一些评论,使得整个问题/答案已经过时,只有历史意义。 - ninjalj

0
将值从标签或变量复制到%%rax

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接