在C中获取标签的地址

Getting the address of a label in C

我在 linux 内核中找到了这个宏,同时试图找出如何在 C

中获取标签的地址
#define _THIS_IP_  ({ __label__ __here; __here: (unsigned long)&&__here; })

而且用法类似

(tsk)->task_state_change = _THIS_IP_; 

我们正在实施我们自己的 OS 作为 Grad OS 课程的一部分,我的目的是在调用 schedule() 之后 return 到标签。 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大概是所有寄存器内容的备份。它可能指向(即包含指针)用户地址 space,而不是内核地址 space.

在标准 C99 或 GNU99 中,不使用 asm 就无法分配寄存器。并且指令指针在 x86-64 上不可分配(你需要一些跳转指令)。

您的 _THIS_IP_ 宏(使用多个 GCC 扩展:statement expressions & local labels & labels as values)只是一种获取当前(或接近)当前地址的方法,作为一个 void* 指针操作说明。该地址稍后可以跳转到,例如间接跳转 (goto *addr;)