是否可以在 C 中访问 32 位寄存器?如果是,如何?如果没有,那么有没有办法在 C 中嵌入汇编代码?顺便说一句,我正在使用 MinGW 编译器。提前致谢!
7 回答
如果您只想读取寄存器,您可以简单地:
register int ecx asm("ecx");
显然它与实例化有关。
另一种方法是使用内联汇编。例如:
asm("movl %%ecx, %0;" : "=r" (value) : );
这会将ecx
值存储到变量value
中。我已经在这里发布了类似的答案。
您要访问哪些寄存器?
通用寄存器通常不能从 C 中访问。您可以在函数中声明寄存器变量,但这并未指定使用哪些特定寄存器。此外,大多数编译器会忽略 register 关键字并自动优化寄存器的使用。
在嵌入式系统中,经常需要访问外设寄存器(例如定时器、DMA 控制器、I/O 引脚)。此类寄存器通常是内存映射的,因此可以从 C...
通过定义一个指针:
volatile unsigned int *control_register_ptr = (unsigned int*) 0x00000178;
或通过使用预处理器:
#define control_register (*(unsigned int*) 0x00000178)
或者,您可以使用组装例程。
对于使用汇编语言,有(至少)三种可能性:
- 与程序链接的单独的 .asm 源文件。汇编例程像普通函数一样从 C 中调用。这可能是最常用的方法,它的优点是硬件相关函数与应用程序代码分离。
- 在线组装
- 执行单个汇编语言指令的内在函数。这样做的好处是汇编语言指令可以直接访问任何 C 变量。
您可以在 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;
}
我不认为你可以直接做。您可以使用以下代码进行内联汇编:
asm (
"movl $0, %%ebx;"
"movl $1, %%eax;"
);
如果您使用的是 32 位处理器并使用适当的编译器,那么可以。确切的方法取决于您正在为其编程的特定系统和编译器,当然这将使您的代码尽可能地不可移植。
在您使用 MinGW 的情况下,您应该查看GCC 的内联汇编语法。
通常不需要从用高级语言编写的程序访问 CPU 寄存器:高级语言,如 C、Pascal 等,正是为了抽象底层机器并使程序更机器化而发明的独立的。
我怀疑您正在尝试执行某些操作,但不知道如何使用传统方式来执行此操作。
许多对寄存器的访问隐藏在更高级别的结构或系统或库调用中,这使您可以避免编码“脏部分”。告诉我们更多关于您想要做什么的信息,我们可能会建议您另一种选择。