C - 读取和设置汇编程序寄存器

问题描述 投票:1回答:3

我需要能够从我的C代码访问汇编寄存器。我有一个简单的方法将寄存器的值设置为变量的值,并将寄存器的值作为变量??希望这有道理......

c gcc assembly cpu-registers
3个回答
3
投票

如果你使用VC(微软的C编译器)

int regVal;
__asm {
  mov [regVal], eax
}

这将加载任何eax持有regVal

如果您正在使用GCC:

int regVal;
asm("movl %%eax, %0" : "=r"(regVal) :);

希望我做对了,我实际上并没有在GCC中进行内联汇编。


2
投票

如果您真的想在执行某些代码时知道寄存器的值,那么使用调试器会更有意义。 (就像gdb与layout asm; layout reg一样)。在没有看到asm代码的情况下查看寄存器值毫无意义。

请参阅 wiki中的链接和指南。


但是,使用GNU inline asm,你可以做类似的事情

int eax_snapshot;
asm volatile (
    ""
    : "=a" (eax_snapshot)
    // no inputs, no clobbers
);
// any amount of intervening code
printf("eax was %x\n", eax_snapshot);  // print whatever eax had at the point where the inline asm appeared in program order

The a constraint表示操作数必须使用%eax寄存器。你的内联asm的主体然后变成无操作,因为你的输出操作数已经告诉编译器了。

无法保证gcc在asm块之前不会发出代码来破坏%eax。这就是为什么这样做没有多大意义。 volatile告诉编译器不要相对于其他源指令重新排序asm语句,但优化仍然意味着早期的初始化被折叠到后来使用它们的代码中。或相反亦然。结合使用this和显式寄存器局部变量可能有助于避免gcc使用您选择的寄存器作为临时寄存器来计算其他东西。 (见下文)。


要设置寄存器,请使用带有"a"约束的内联asm来强制该操作数的值在%eax(或%ebx约束的"b"等,请参阅x86特定的机器约束的文档)在内联asm出现的位置。如果要实际使用该寄存器值,请从内联asm语句中进行,否则可能会被其他内容覆盖。


您还可以声明必须在特定寄存器中分配的变量,但我认为在没有初始化的情况下使用它们会使编译器不满意。 (代码转换通过检测未定义的行为,例如这可能会导致问题.IDK。)语法将是

register int eax asm ("eax");  // don't do this to read eax, it probably doesn't do what you think it would

The docs make it sound like using it for reading registers is not going to be a good idea.但是,为了设置寄存器值,这应该很好。 (只要寄存器分配器接受您的提示并将该变量保存在请求的寄存器中。)


除非你有充分的理由,否则不要这样做。它对于正常编程非常不可能有用。正常的内联asm或调用函数是组合C和asm的更好方法。这只有在您想要在程序的内部状态下进行某种kludgy戳时才有用。

既然你没有给出你想要这个的用例,我强烈建议你不要写代码来做这件事。这听起来很难看。


0
投票

由于您使用的是gcc,因此以下是在gcc:https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#AssemblerTemplate中使用asm模板的文档

要设置寄存器的值,您可以执行以下操作:

uint64_t rax = 0;
__asm__ __volatile__("mov %0, %%rax\n\t"
                     : /* no output */
                     : "a" (rax)
                     : "%rax");

为了读取寄存器的值,您将执行以下操作:

uint64_t rax;
__asm__ __volatile__("mov %%rax, %0\n\t"
                     : "=a"(rax)
                     : /* no input */
                     : /* no clobbers */);
© www.soinside.com 2019 - 2024. All rights reserved.