12

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

4

7 回答 7

17

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

register int ecx asm("ecx");

显然它与实例化有关。

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

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

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

于 2010-06-11T10:44:57.470 回答
7

您要访问哪些寄存器?

通用寄存器通常不能从 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 变量。
于 2010-06-11T12:19:53.080 回答
1

您可以在 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;
}
于 2010-06-11T10:38:10.930 回答
0

我不认为你可以直接做。您可以使用以下代码进行内联汇编:

asm (
    "movl $0, %%ebx;"
    "movl $1, %%eax;"
); 
于 2010-06-11T10:38:43.017 回答
0

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

在您使用 MinGW 的情况下,您应该查看GCC 的内联汇编语法

于 2010-06-11T10:39:05.310 回答
0

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

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

于 2010-06-11T11:22:11.557 回答
-1

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

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

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

于 2010-06-11T10:42:35.333 回答