我在 linux 内核中发现了这个宏,同时试图找出如何在 C 中获取标签的地址
#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })
它的用法是这样的
(tsk)->task_state_change = _THIS_IP_;
作为 Grad OS 类(class)的一部分,我们正在实现我们自己的操作系统,我的目的是在调用 schedule()
后返回到标签。 Linux 内核通过上述宏以某种方式实现了这一点。
不应该这样吗? (请假设我在下面有必要的程序集来读写寄存器。这只是我想展示的伪代码,以强调我打算如何获取标签的地址)
register_struct.rip = &&ret; /* GCC extension '&&' */
/* register_struct is a structure that holds all the registers of
* a process. Its useful to save and restore a process' state
*/
schedule();
ret: /* some code here */
我真的不明白 Linux 内核代码如何通过 _THIS_IP_
实现相同的目的。
最佳答案
register_struct
大概是所有寄存器内容的备份。它可能指向(即包含指针)用户地址空间,而不是内核地址空间。
在标准 C99 或 GNU99 中,不使用 asm
就无法分配寄存器。并且指令指针在 x86-64 上不可分配(您需要一些跳转指令)。
您的 _THIS_IP_
宏(使用多个 GCC 扩展:statement expressions & local labels & labels as values )只是一种获取方式,作为 void*
指针,当前指令的(或接近)地址。该地址稍后可以跳转到,例如使用间接跳转 (goto *addr;
)
关于c - 在C中获取标签的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29713187/