2010-06-11 2 views
8

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

+1

расскажите нам больше о ваших потребностях: почему вы хотите получить доступ к регистрам CPU ??? –

+0

Вы можете косвенно получать и устанавливать регистры в окнах с помощью GetThreadContext и его брата SetThreadContext, без каких-либо необходимых asm: http://msdn.microsoft.com/en-us/library/ms679362%28VS.85%29.aspx – Necrolis

ответ

12

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

register int ecx asm("ecx"); 

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

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

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

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

+0

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

1

Вы можете встроить в сборку C

http://en.wikipedia.org/wiki/Inline_assembler

пример из википедии

ехЬегп 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

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

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

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

В вашем случае с использованием MinGW вы должны посмотреть на GCC's inline assembly syntax.

+1

Спасибо много для ссылки! Очень полезно. – C4theWin

-2

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

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

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

+0

Нет, я действительно точно знаю, что я делаю. Но спасибо, что помогли мне. :) – C4theWin

+0

-1: Ответ не имеет отношения к вопросу. – Sparky

0

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

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

7

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

С обычным доступом к объектам с общим кодом нельзя получить доступ из 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. Внутренние функции, выполняющие отдельные инструкции языка ассемблера. Это имеет то преимущество, что инструкция языка ассемблера может напрямую обращаться к любым переменным С.
+0

Как вы можете получить этот номер 0x00000178? – Garmekain

Смежные вопросы