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

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

11
задан starblue 11 June 2010 в 19:16
поделиться

7 ответов

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

register int ecx asm("ecx");

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

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

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

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

15
ответ дан 3 December 2019 в 05:33
поделиться

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

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

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

путем определения указателя:

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

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

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

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

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

  1. Отдельный исходный файл .asm, связанный с программой. Подпрограммы сборки вызываются из C как обычные функции. Это, вероятно, наиболее распространенный метод, и его преимущество состоит в том, что функции, зависящие от hw, отделены от кода приложения.
  2. Встроенная сборка
  3. Внутренние функции, выполняющие отдельные инструкции на языке ассемблера. Это имеет то преимущество, что инструкция на языке ассемблера может напрямую обращаться к любым переменным C.
7
ответ дан 3 December 2019 в 05:33
поделиться

Вы можете встроить ассемблер в 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;
}
1
ответ дан 3 December 2019 в 05:33
поделиться

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

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

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

-2
ответ дан 3 December 2019 в 05:33
поделиться

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

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

0
ответ дан 3 December 2019 в 05:33
поделиться

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

asm (
    "movl $0, %%ebx;"
    "movl $1, %%eax;"
); 
0
ответ дан 3 December 2019 в 05:33
поделиться

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

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

0
ответ дан 3 December 2019 в 05:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: