Lev*_*evi 3 c inline-assembly cpu-registers
最近我一直在使用C中的内联汇编,并且想知道我是否可以直接从变量访问寄存器
像这样的东西:
volatile uint64_t* flags = RFLAGS;
Run Code Online (Sandbox Code Playgroud)
其中RFLAGS是CPU标志寄存器.显然,上面的代码没有编译,但我想知道是否有类似的方法来实现所需的结果.
使用gcc编译Ubuntu x86_64
您可以通过内联asm获取标志寄存器的值,但此操作没有用,因为您无法控制与其他操作相关的访问顺序.特别是,你可能想要的是因为某些特定算术运算产生的标志在你的asm块的开头是可用的,但是没有办法向编译器表达那个约束.例如,假设您写道:
z = x + y;
__asm__ ( "pushf ; pop %0" : "=r"(flags) );
Run Code Online (Sandbox Code Playgroud)
您可能希望添加产生的标记可用.但是,编译器可能选择:
add/ sub中间调整堆栈指针,破坏标志.lea而不是add实现添加,不产生标志.同样的原则适用于访问可能由编译器生成的代码修改的任何寄存器.存在是一个语法(在GCC /"GNU C"),用于访问寄存器不受这一问题; 看起来像:
register int var __asm__("regname");
Run Code Online (Sandbox Code Playgroud)
where regname由注册名称替换.这在大多数目标上基本上没用,但是它可以允许您控制输入/输出约束的寄存器使用到asm,并且一些目标具有永久保存在通用寄存器中的特殊值(线程本地存储指针是最常见的)这在某些情况下可能有用.