C语言可以访问32位寄存器吗?

发布于 2024-09-04 20:42:04 字数 87 浏览 4 评论 0原文

C语言可以访问32位寄存器吗?如果是的话,怎么样?如果没有,那么有什么方法可以在 C 中嵌入汇编代码吗?顺便说一句,我正在使用 MinGW 编译器。 提前致谢!

Is it possible to access 32-bit registers in C ? If it is, how ? And if not, then is there any way to embed Assembly code in C ? I`m using the MinGW compiler, by the way.
Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

回忆躺在深渊里 2024-09-11 20:42:04

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

register int ecx asm("ecx");

显然它与实例化相关。

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

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

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

If you want to only read the register, you can simply:

register int ecx asm("ecx");

Obviously it's tied to instantiation.

Another way is using inline assembly. For example:

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

This stores the ecx value into the variable value. I've already posted a similar answer here.

┊风居住的梦幻卍 2024-09-11 20:42:04

您想访问哪些寄存器?

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

在嵌入式系统中,经常需要访问外设寄存器(例如定时器、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 变量。

Which registers do you want to access?

General purpose registers normally can not be accessed from C. You can declare register variables in a function, but that does not specify which specific registers are used. Further, most compilers ignore the register keyword and optimize the register usage automatically.

In embedded systems, it is often necessary to access peripheral registers (such as timers, DMA controllers, I/O pins). Such registers are usually memory-mapped, so they can be accessed from C...

by defining a pointer:

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

or by using pre-processor:

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

Or, you can use Assembly routine.

For using Assembly language, there are (at least) three possibilities:

  1. A separate .asm source file that is linked with the program. The assembly routines are called from C like normal functions. This is probably the most common method and it has the advantage that hw-dependent functions are separated from the application code.
  2. In-line assembly
  3. Intrinsic functions that execute individual assembly language instructions. This has the advantage that the assembly language instruction can directly access any C variables.
喜你已久 2024-09-11 20:42:04

您可以在 C

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

示例 中嵌入程序集来自维基百科

extern int errno;

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;
}

You can embed assembly in C

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

example from wikipedia

extern int errno;

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;
}
救赎№ 2024-09-11 20:42:04

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

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

I don't think you can do them directly. You can do inline assembly with code like:

asm (
    "movl $0, %%ebx;"
    "movl $1, %%eax;"
); 
作业与我同在 2024-09-11 20:42:04

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

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

If you are on a 32-bit processor and using an adequate compiler, then yes. The exact means depends on the particular system and compiler you are programming for, and of course this will make your code about as unportable as can be.

In your case using MinGW, you should look at GCC's inline assembly syntax.

橘味果▽酱 2024-09-11 20:42:04

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

讨论 gcc 汇编的相关页面是 这里此处,如果需要,还可以此处。不要忘记它不能是特定的,因为它依赖于体系结构(gcc 可以针对多个 cpu 进行编译)

You can of course. "MinGW" (gcc) allows (as other compilers) inline assembly, as other answers already show. Which assembly, it depends on the cpu of your system (prob. 99.99% that it is x86). This makes however your program not portable on other processors (not that bad if you know what you are doing and why).

The relevant page talking about assembly for gcc is here and here, and if you want, also here. Don't forget that it can't be specific since it is architecture-dependent (gcc can compile for several cpus)

青芜 2024-09-11 20:42:04

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

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

对寄存器的许多访问隐藏在更高级别的构造或系统或库调用中,这可以让您避免编码“脏部分”。请告诉我们更多有关您想要做什么的信息,我们可能会向您建议替代方案。

there is generally no need to access the CPU registers from a program written in a high-level language: high-level languages, like C, Pascal, etc. where precisely invented in order to abstract the underlying machine and render a program more machine-independent.

i suspect you are trying to perform something but have no clue how to use a conventional way to do it.

many access to the registers are hidden in higher-level constructs or in system or library calls which lets you avoid coding the "dirty-part". tell us more about what you want to do and we may suggest you an alternative.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文