Можно ли получить доступ к 32-битным регистрам в C? - PullRequest
10 голосов
/ 11 июня 2010

Возможно ли получить доступ к 32-битным регистрам в C? Если это так, как? А если нет, то есть ли способ встраивать ассемблерный код в C? Кстати, я пользуюсь компилятором MinGW. Заранее спасибо!

Ответы [ 7 ]

14 голосов
/ 11 июня 2010

Если вы хотите только читать регистр, вы можете просто:

register int ecx asm("ecx");

Очевидно, это связано с реализацией.

Другой способ - использовать встроенную сборку.Например:

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

Сохраняет значение ecx в переменной value.Я уже отправил подобный ответ здесь .

7 голосов
/ 11 июня 2010

К каким регистрам вы хотите обращаться?

Регистры общего назначения обычно недоступны из C. Вы можете объявить переменные регистра в функции, но это не указывает, какие конкретныерегистры используются.Кроме того, большинство компиляторов игнорируют ключевое слово register и автоматически оптимизируют использование регистра.

Во встроенных системах часто требуется доступ к периферийным регистрам (таким как таймеры, контроллеры DMA, ввод / вывод).штифты).Такие регистры обычно отображаются в память, поэтому к ним можно получить доступ из C ...

, указав указатель:

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

или используя препроцессор:

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

Или вы можете использовать процедуру сборки.

Для использования Язык сборки существует (как минимум) три возможности:

  1. Отдельно.Исходный файл asm, связанный с программой.Процедуры сборки вызываются из C как обычные функции.Это, вероятно, самый распространенный метод, и его преимущество заключается в том, что hw-зависимые функции отделены от кода приложения.
  2. Встроенная сборка
  3. Встроенные функции, которые выполняют отдельные инструкции на языке ассемблера.Это дает преимущество в том, что инструкция на ассемблере может напрямую обращаться к любым переменным Си.
1 голос
/ 11 июня 2010

Вы можете встроить сборку в 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;
}
0 голосов
/ 11 июня 2010

Можно конечно. MinGW (gcc) позволяет (как и другие компиляторы) встроенную сборку, как уже показывают другие ответы. Какая сборка зависит от процессора вашей системы (вероятно, 99,99%, что это x86). Однако это делает вашу программу не переносимой на другие процессоры (не так уж плохо, если вы знаете, что делаете и почему).

На соответствующей странице, посвященной сборке для gcc, есть здесь и здесь , и, если хотите, также здесь . Не забывайте, что он не может быть конкретным, поскольку он зависит от архитектуры (gcc может компилироваться для нескольких процессоров)

0 голосов
/ 11 июня 2010

как правило, нет необходимости обращаться к регистрам ЦП из программы, написанной на языке высокого уровня: языках высокого уровня, таких как C, Pascal и т. Д., Где они точно придуманы, чтобы абстрагировать базовую машину и визуализировать программуболее независимый от машины.

я подозреваю, что вы пытаетесь выполнить что-то, но не знаете, как использовать обычный способ сделать это.

многие доступ к регистрам скрыты в конструкциях более высокого уровня или в системе илибиблиотечные вызовы, которые позволяют избежать кодирования «грязной части».расскажите нам больше о том, что вы хотите сделать, и мы можем предложить вам альтернативу.

0 голосов
/ 11 июня 2010

Если вы используете 32-разрядный процессор и используете подходящий компилятор, тогда да. Точное значение зависит от конкретной системы и компилятора, для которого вы программируете, и, конечно, это сделает ваш код настолько непереносимым, насколько это возможно.

В вашем случае, используя MinGW, вы должны посмотреть Синтаксис встроенной сборки GCC .

0 голосов
/ 11 июня 2010

Я не думаю, что вы можете сделать это напрямую.Вы можете выполнить встроенную сборку с кодом, подобным:

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