OSDev

для всех
Текущее время: 10 май 2024, 02:16

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: GCC long jump
СообщениеДобавлено: 27 ноя 2010, 07:17 

Зарегистрирован: 10 июн 2010, 15:14
Сообщения: 3
Откуда: Беларусь, Витебск
Нужно сделать длинный прыжок на функцию

Код:
void *func;

void someproc(){ //надо сюда
...
}

void main(){
...
   func = (void*)someproc; //получть адрес функции
   __asm__("lgdt gdtr");
   __asm__("lcall $8, $func");
}


Насколько мне известно, $func даёт адрес переменной, посему прыжок не выходит. Как вставить значение переменной?
(такой код
Код:
__asm__("lcall $8, func");

не компилируется).

Если вместо
Код:
 __asm__("lcall $8, $func");

поставить абсолютный адрес
Код:
__asm__("lcall $8, $0xC0000000");
, то всё работает как надо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: GCC long jump
СообщениеДобавлено: 27 ноя 2010, 11:42 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1418
Я с GCC не работаю, но могу сказать, что в таком варианте одной командой перехода не обойтись: система команд ИА-32 не обеспечивает возможность перехода к подпрограмме по адресу, хранящемуся в памяти, как это имеет место быть в Вашем случае. По всей вероятности, здесь придётся действовать через задницу: 1) запихнуть вручную в стек адрес возврата; 2) запихнуть в стек адрес перехода; 3) выполнить дальний RET, который и выполнит переход к нужной подпрограмме.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: GCC long jump
СообщениеДобавлено: 27 ноя 2010, 21:46 

Зарегистрирован: 10 июн 2010, 15:14
Сообщения: 3
Откуда: Беларусь, Витебск
Спасибо, помогло.
Я только недавно пересел на GCC/AT&T, раньше программил на Pascal/Intel.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: GCC long jump
СообщениеДобавлено: 27 ноя 2010, 22:13 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1418
Ну, я под Винду пишу исключительно на Дельфях, а не под Винду -- на асме, плюс экспериментирую с Адой (из ГЦЦ) и ФриПаскалем. Си/Си++ ненавижу, не использую и не собираюсь (кроме как в случаях, когда по работе это прямо требуется).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: GCC long jump
СообщениеДобавлено: 28 ноя 2010, 15:04 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
The Odd Beard, изучи типы адресации в Ассемблере. Такого непосредственно-косвенного вызова не бывает. В твоём примере первый операнд, который номер селектора, это непосредственное значение, а второй операнд, который линейный адрес, это косвенное значение, тоесть ты всё смешал. Правильно, что вторая запись, где ты прописываешь оба непосредственных значения, у тебя сработала, так и должно быть. А если надо сделать косвенный вызов, то оба значения должны находиться в переменной-указателе, а в инструкции call прописан только адрес указателя. Сам указатель надо расширить до двух значений.
Примерно так, я не проверял. Но основной принцип такой:
Код:
int func[2]; //Первое значение - линейный адрес, второе - селектор.
func[0] = (int)&some_proc;
func[1] = 8;
asm("lcall FAR PTR $func");


После команды компиляции вызови ту же компиляцию, только с параметром -S, при этом создастся ассемблерный файл - эквивалент исходной Си программы. Файл появится с расширением .s. По нему проверишь результат.
Ещё совет - компилятору можно указать параметр
-masm=intel
тогда ассемблерные вставки можно будет писать в синтаксисе Intel.
asm("call FAR PTR [func]");


Последний раз редактировалось Himik 30 ноя 2010, 17:40, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: GCC long jump
СообщениеДобавлено: 30 ноя 2010, 03:44 

Зарегистрирован: 10 июн 2010, 15:14
Сообщения: 3
Откуда: Беларусь, Витебск
chizh, спасибо.
Поэкспериментировал с твоим методом.
Код:
typedef struct jmptr{
  void* addr;
  unsigned short segment;
} jmptr;
...
jmptr jtag;

void main(){
...
func = &somefunc;
jtag.segment = 8;
jtag.addr = func;
__asm__("lcall (jtag)");
}

Вот так работает.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB