【问题标题】:Is it possible to access 32-bit registers in C?是否可以在 C 中访问 32 位寄存器?
【发布时间】:2011-03-02 14:40:42
【问题描述】:

是否可以在 C 中访问 32 位寄存器?如果是,如何?如果没有,那么有没有办法在 C 中嵌入汇编代码?顺便说一句,我正在使用 MinGW 编译器。 提前致谢!

【问题讨论】:

标签: c assembly mingw inline-assembly cpu-registers


【解决方案1】:

如果你只想读取寄存器,你可以简单地:

register int ecx asm("ecx");

显然它与实例化有关。

另一种方法是使用内联汇编。例如:

asm("movl %%ecx, %0;" : "=r" (value) : );

这会将ecx 值存储到变量value 中。我已经发布了类似的答案here

【讨论】:

  • 非常感谢代码示例。我需要的确切信息。 ;)
【解决方案2】:

您要访问哪些寄存器?

通用寄存器通常不能从 C 中访问。您可以在函数中声明寄存器变量,但这并不指定使用哪些特定寄存器。此外,大多数编译器会忽略 register 关键字并自动优化寄存器的使用。

在嵌入式系统中,经常需要访问外设寄存器(例如定时器、DMA 控制器、I/O 引脚)。此类寄存器通常是内存映射的,因此可以从 C... 访问它们。

通过定义一个指针:

volatile unsigned int *control_register_ptr = (unsigned int*) 0x00000178;

或使用预处理器:

#define control_register (*(unsigned int*) 0x00000178)

或者,您可以使用汇编程序。

对于使用汇编语言,有(至少)三种可能性:

  1. 与程序链接的单独的 .asm 源文件。汇编例程像普通函数一样从 C 中调用。这可能是最常用的方法,它的优点是硬件相关函数与应用程序代码分离。
  2. 在线组装
  3. 执行单个汇编语言指令的内部函数。这样做的好处是汇编语言指令可以直接访问任何 C 变量。

【讨论】:

  • 你怎么能得到那个 0x00000178 号码?
【解决方案3】:

您可以在 C 中嵌入程序集

http://en.wikipedia.org/wiki/Inline_assembler

来自维基百科的示例

外部错误码;

int funcname(int arg1, int *arg2, int arg3)
{
  int res;
  __asm__ volatile(
    "int $0x80"        /* make the request to the OS */
    : "=a" (res)       /* return result in eax ("a") */
      "+b" (arg1),     /* pass arg1 in ebx ("b") */
      "+c" (arg2),     /* pass arg2 in ecx ("c") */
      "+d" (arg3)      /* pass arg3 in edx ("d") */
    : "a"  (128)       /* pass system call number in eax ("a") */
    : "memory", "cc"); /* announce to the compiler that the memory and condition codes have been modified */

  /* The operating system will return a negative value on error;
   * wrappers return -1 on error and set the errno global variable */
  if (-125 <= res && res < 0) {
    errno = -res;
    res   = -1;
  }  
  return res;
}

【讨论】:

    【解决方案4】:

    我认为您不能直接执行这些操作。您可以使用以下代码进行内联汇编:

    asm (
        "movl $0, %%ebx;"
        "movl $1, %%eax;"
    ); 
    

    【讨论】:

      【解决方案5】:

      如果您使用 32 位处理器并使用适当的编译器,那么可以。确切的方法取决于您正在为其编程的特定系统和编译器,当然这将使您的代码尽可能地不可移植。

      在您使用 MinGW 的情况下,您应该查看 GCC's inline assembly syntax

      【讨论】:

      • 非常感谢您的链接!非常有用。
      【解决方案6】:

      当然可以。正如其他答案已经显示的那样,“MinGW”(gcc)允许(作为其他编译器)内联汇编。哪个程序集,取决于您系统的 CPU(可能 99.99% 是 x86)。然而,这使得您的程序无法在其他处理器上移植(如果您知道自己在做什么以及为什么这样做,那还不错)。

      讨论 gcc 汇编的相关页面是 herehere,如果你愿意,也可以是 here。不要忘记它不能具体,因为它是依赖于架构的(gcc可以编译多个cpu)

      【讨论】:

        【解决方案7】:

        通常不需要从用高级语言编写的程序访问 CPU 寄存器:高级语言,如 C、Pascal 等,正是为了抽象底层机器和渲染程序而发明的更独立于机器。

        我怀疑您正在尝试执行某些操作,但不知道如何使用传统方式来执行此操作。

        许多对寄存器的访问隐藏在更高级别的构造或系统或库调用中,这使您可以避免编写“脏部分”。告诉我们更多关于您想要做什么的信息,我们可能会建议您另一种选择。

        【讨论】:

        • 不,我其实很清楚自己在做什么。但是谢谢你帮助我。 :)
        猜你喜欢
        • 2011-10-18
        • 1970-01-01
        • 2014-11-18
        • 2018-07-23
        • 1970-01-01
        • 2023-03-29
        • 2020-11-21
        • 1970-01-01
        相关资源
        最近更新 更多