是否可以在C中访问32位寄存器?如果是的话,怎么样?如果没有,那么有没有办法在C中嵌入汇编代码?顺便说一下,我正在使用MinGW编译器。 提前谢谢!
答案 0 :(得分:14)
如果您只想阅读寄存器,可以简单地说:
register int ecx asm("ecx");
显然它与实例化有关。
另一种方法是使用内联汇编。例如:
asm("movl %%ecx, %0;" : "=r" (value) : );
这会将ecx
值存储到变量value
中。我已经发布了类似的答案here。
答案 1 :(得分:7)
您想访问哪些注册表?
通常无法从C访问通用寄存器。您可以在函数中声明寄存器变量,但不指定使用哪些特定寄存器。此外,大多数编译器会忽略register关键字并自动优化寄存器使用情况。
在嵌入式系统中,通常需要访问外设寄存器(例如定时器,DMA控制器,I / O引脚)。这些寄存器通常是内存映射的,因此可以从C ...
访问它们通过定义指针:
volatile unsigned int *control_register_ptr = (unsigned int*) 0x00000178;
或使用预处理器:
#define control_register (*(unsigned int*) 0x00000178)
或者,您可以使用汇编例程。
对于使用汇编语言,有(至少)三种可能性:
答案 2 :(得分:1)
您可以在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;
}
答案 3 :(得分:0)
我认为你不能直接做到。 可以使用以下代码进行内联汇编:
asm (
"movl $0, %%ebx;"
"movl $1, %%eax;"
);
答案 4 :(得分:0)
如果您使用的是32位处理器并且使用了足够的编译器,那么是的。确切的方法取决于您编程的特定系统和编译器,当然这将使您的代码尽可能不可移植。
在使用MinGW的情况下,您应该查看GCC's inline assembly syntax。
答案 5 :(得分:0)
你当然可以。 “MinGW”(gcc)允许(与其他编译器一样)内联汇编,正如其他答案已经显示的那样。哪个程序集,它取决于你的系统的CPU(概率99.99%,它是x86)。这使得您的程序无法在其他处理器上移植(如果您知道自己在做什么以及为什么会这么做,那就太糟糕了。)
关于gcc汇编的相关网页是here和here,如果您愿意,还可以here。不要忘记它不能具体,因为它依赖于体系结构(gcc可以编译几个cpus)
答案 6 :(得分:-2)
通常不需要从以高级语言编写的程序访问CPU寄存器:高级语言,如C,Pascal等,其中精确发明以抽象底层机器并呈现程序更多机器独立。
我怀疑你正在尝试执行某些操作但却不知道如何使用传统方法来执行此操作。
许多对寄存器的访问都隐藏在更高级别的构造或系统或库调用中,这使您可以避免编写“脏部分”。告诉我们更多关于你想做什么的事情,我们可能会建议你做一个替代方案。