изучение и изменение адресов памяти в C - PullRequest
1 голос
/ 16 марта 2012

Я хочу, по сути, сделать следующее (что, вероятно, опасно, а что нет) только для этого:

int main() {

    int x = 0x00ff00ff;

    printf("Value at addr x: %x\n",*x);


    return 0;
}

В основном взгляните на содержимое определенного адреса в моей машине.Может быть, написать в него.Я предполагаю, что мне не позволено делать последнее.

Я получаю ошибку error: invalid type argument of 'unary *'.

Есть ли способ сделать это?

Ответы [ 2 ]

6 голосов
/ 16 марта 2012

Вам нужен указатель :

int *x = (int*)0x00ff00ff;

И вы правы, это, вероятно, не очень хорошая идея, если вы не знаете , что 0x00ff00ff является действительным адресом какого-то рода. На самом деле это не неопределенное поведение, так как стандарт говорит, что вы не можете разыменовать нелегальные адреса, но затем заявляет, что "нелегальные" включают в себя такие вещи, как:

  • адреса освобожденных объектов кучи.
  • пустые указатели.
  • неправильное выравнивание.

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

Например, вы можете управлять UART (универсальным асинхронным приемником / передатчиком, в основном устройством последовательного порта) во встроенной системе, читая или записывая известные адреса ввода-вывода с отображением в памяти:

#define UART_READ_READY  ((char*)0xff00)
#define UART_READ_CLEAR  ((char*)0xff01)
#define UART_DATA        ((char*)0xff02)

char getUartCharWithWait (unsigned int tries) {
    char retChar;
    unsigned int limit;

    // Keep looping until character available, at least for a while.

    limit = tries;
    while (*UART_READ_READY == 0)
        if (limit-- == 0)
            return '\0';

    // Get character, tell UART to clear it, then return it.

    retChar = *UART_DATA;
    *UART_CLEAR = 1;

    return retChar;
}

В этом примере у вас есть такой код:

retChar = *UART_DATA;

, который будет считывать байт (C char) с адреса «памяти» 0xff02, который на самом деле будет поступать с устройства, которое контролирует адресную шину и перехватывает определенные адреса.

4 голосов
/ 16 марта 2012

Вы получаете ранее упомянутую ошибку, потому что нет способа разыменования и int, поэтому x указатель на int приведет к "правильному"результат (т. е. он будет в состоянии скомпилировать).

int * x = (int*)0x00ff00ff;

"Это работает, ЭТО РАБОТАЕТ!Теперь, что такое segfault?"

...