Можно ли получить доступ к 32-битным регистрам в C?

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


person C4theWin    schedule 11.06.2010    source источник
comment
расскажите нам больше о ваших потребностях: зачем вам доступ к регистрам ЦП ???   -  person Adrien Plisson    schedule 11.06.2010
comment
вы можете косвенно получать и устанавливать регистры в окнах, используя GetThreadContext и его брата SetThreadContext, без необходимости использования asm: msdn.microsoft.com/en-us/library/ms679362%28VS.85%29.aspx   -  person Necrolis    schedule 13.06.2010


Ответы (7)


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

register int ecx asm("ecx");

Очевидно, это связано с созданием экземпляров.

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

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

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

person jweyrich    schedule 11.06.2010
comment
Большое спасибо за примеры кода. Точная информация, которая мне была нужна. ;) - person C4theWin; 11.06.2010

К каким регистрам вы хотите получить доступ?

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

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

определяя указатель:

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

или с помощью препроцессора:

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

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

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

  1. Отдельный исходный файл .asm, связанный с программой. Подпрограммы ассемблера вызываются из C как обычные функции. Это, вероятно, наиболее распространенный метод, и его преимущество заключается в том, что аппаратно-зависимые функции отделены от кода приложения.
  2. Поточная сборка
  3. Встроенные функции, выполняющие отдельные инструкции языка ассемблера. Это имеет то преимущество, что инструкция языка ассемблера может напрямую обращаться к любым переменным C.
person PauliL    schedule 11.06.2010
comment
Как вы можете получить этот номер 0x00000178? - person Garmekain; 05.09.2016

Вы можете встроить сборку в 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;
}
person Charles Ma    schedule 11.06.2010

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

asm (
    "movl $0, %%ebx;"
    "movl $1, %%eax;"
); 
person paxdiablo    schedule 11.06.2010

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

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

person Crashworks    schedule 11.06.2010
comment
Большое спасибо за ссылку! Очень полезно. - person C4theWin; 11.06.2010

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

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

person ShinTakezou    schedule 11.06.2010

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

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

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

person Adrien Plisson    schedule 11.06.2010
comment
Нет, я точно знаю, что делаю. Но спасибо, что выручил меня. :) - person C4theWin; 11.06.2010