Действительно ли возможно получить доступ к 32-разрядным регистрам в C? Если это, как? И в противном случае затем есть ли какой-либо способ встроить Ассемблерный код в C? Я использую компилятор MinGW, между прочим.Заранее спасибо!
Если вы хотите только читать регистр, вы можете просто:
register int ecx asm("ecx");
Очевидно, это связано с созданием экземпляра.
Другой способ - использовать встроенную сборку. Например:
asm("movl %%ecx, %0;" : "=r" (value) : );
Сохраняет значение ecx
в значение переменной
. Я уже публиковал аналогичный ответ здесь .
К каким регистрам вы хотите получить доступ?
Регистры общего назначения обычно не доступны из C. Вы можете объявить регистровые переменные в функции, но это не определяет, какие именно регистры используются. Кроме того, большинство компиляторов игнорируют ключевое слово register и автоматически оптимизируют использование регистров.
Во встроенных системах часто требуется доступ к периферийным регистрам (например, таймерам, контроллерам прямого доступа к памяти, контактам ввода-вывода). Такие регистры обычно отображаются в памяти, поэтому к ним можно получить доступ из C ...
путем определения указателя:
volatile unsigned int *control_register_ptr = (unsigned int*) 0x00000178;
или с помощью препроцессора:
#define control_register (*(unsigned int*) 0x00000178)
Или вы можете использовать процедуру ассемблера.
Для использования языка ассемблера существует (как минимум) три возможности:
Вы можете встроить ассемблер в 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;
}
Обычно нет необходимости обращаться к регистрам процессора из программы, написанной на языке высокого уровня: языки высокого уровня, такие как C, Pascal и т.д., были придуманы именно для того, чтобы абстрагировать базовую машину и сделать программу более машинно-независимой.
я подозреваю, что вы пытаетесь что-то сделать, но не знаете, как это сделать обычным способом.
многие доступы к регистрам скрыты в конструкциях более высокого уровня или в системных или библиотечных вызовах, что позволяет вам избежать кодирования "грязной части". расскажите нам больше о том, что вы хотите сделать, и мы можем предложить вам альтернативу.
Если вы на 32-битном процессоре и используете адекватный компилятор, то да. Точное средство зависит от конкретной системы и компилятора, под который вы программируете, и, конечно, это сделает ваш код настолько непортативным, насколько это вообще возможно.
В вашем случае с использованием MinGW, вам следует обратить внимание на синтаксис встроенного ассемблера GCC.
Я не думаю, что вы можете делать это напрямую. Вы можете сделать inline assembly с кодом типа:
asm (
"movl $0, %%ebx;"
"movl $1, %%eax;"
);
Конечно, вы можете. «MinGW» (gcc) позволяет (как и другие компиляторы) встроенную сборку, как уже показывают другие ответы. Какая сборка, зависит от процессора вашей системы (вероятность 99,99%, что это x86). Однако это делает вашу программу не переносимой на другие процессоры (не так уж и плохо, если вы знаете, что делаете и почему).
Соответствующая страница, посвященная сборке для gcc, находится здесь и здесь , и, если хотите, также здесь . Не забывайте, что он не может быть конкретным, поскольку он зависит от архитектуры (gcc может компилироваться для нескольких процессоров)