Доступ к памяти блокнота из C - PullRequest
5 голосов
/ 14 июля 2010

Это может быть немного экзотической проблемой, но я надеюсь, что кто-то еще может помочь мне немного;).Я хотел бы выполнить стандартную программу на C, однако в какой-то момент во время выполнения программы мне бы хотелось, чтобы выполнялось определенное количество инструкций, которые хранятся в локальной памяти ОЗУ.Память блокнота доступна для всех процессов.Предположим, что эта локальная память начинается с адреса 0x80000000, и я интегрировал бы это в следующий код C-кода

int main {
int a=1;
int b=2;
int c=3;    

c = a + b;

%goto address 0x80000000 and execute three instructions before continuing
%program execution here 

return(0);

}

Счетчик программы прошел бы следующие этапы, предполагая, что main загруженна 0x40000000

0x40000000    a=5; 
0x40000004    b=2; 
0x40000008    c=1;  
0x4000000C    c=a+b;
0x80000000    first instruction in the local scratch pad
0x80000004    second instruction in the local scratch pad
0x80000008    third instruction in the local scratch pad  
0x40000010    return(0);

Кто-нибудь знает, как это сделать?Нужно ли использовать инструкции ассемблерного перехода или есть что-то более элегантное.

Большое спасибо, Анди

Ответы [ 4 ]

6 голосов
/ 14 июля 2010

Предполагая, что инструкции ведут себя как обычная функция, вы можете сделать:

#include <stdio.h>

void (*scratchpad_func)(void) = (void(*)(void))0x80000000;

int main()
{
    printf("before\n");
    scratchpad_func();
    printf("after\n");
    return 0;
}

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

(На некоторых архитектурах "вести себя как обычная функция" так же просто, как "jump $ ra" в конце, если вы не касаетесь сохраненных вызываемыми регистрами.

1 голос
/ 14 июля 2010

Ни приведение адреса к указателю функции, ни встроенному ассемблеру не нормализовано, так что ничего из этого не будет переносимым; -)

Отображение фиксированного адреса, как упоминает Карл, возможно с POSIX, но, опять же, для его выполнения нет простого способа.

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

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

0 голосов
/ 14 июля 2010

Хорошо, пара подсказок.

  1. Необходимо убедиться, что память в «блокноте» является адресуемой и исполняемой.
  2. Убедитесь, что последовательность инструкций вячейка памяти заканчивается кодом ret
  3. call, а не переходом к нему.
0 голосов
/ 14 июля 2010

Чтобы перейти к фиксированному местоположению, вы можете объявить тип, который является указателем на функцию, затем привести ваш адрес к этому типу и вызвать его как функцию.

Если вы хотите, чтобы эта область памяти была доступна для процессов, отличных от вашей программы, вам придется использовать примитивы разделяемой памяти вашей операционной системы (Windows / Linux / OS X) для сопоставления порции памяти с выбранным вами адресом.

Звучит как безумная идея, но ее можно заставить работать. Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...