Официальный форум СВД Встраиваемые Системы
03 Декабря, 2016, 07:37:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
 
 
 Сайт СВД ВС  Начало   Помощь Поиск Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Вставка на ассемблере  (Прочитано 1112 раз)
LH
Опытный пользователь

Сообщений: 249


« : 11 Августа, 2011, 17:52:50 »

; чтение массива из памяти данных платы
   push    di
   cld
   mov   ax, 2000H   ; начальный адрес памяти (первые 14 разрядов)
   or   ax, 4000H   ; ‘1’ в 14-ом разряде означает память данных
   mov   dx, cs:IDMA_ADDRESS_REG   ; адрес порта для записи начального адреса IDMA
   out   dx, ax   ; посылаем начальный адрес IDMA
   les   di, pBuffer      ; адрес буфера получаемых данных (имеет тип DWORD)
   mov   cx, 1024      ; счетчик числа вводимых данных
   mov   dx, cs:IDMA_DATA_REG   ; адрес порта данных IDMA
   repe   insw   ; принимаем данные
   pop   di


Не удается  сделать такую асемблерную вставку в текст программы на С (С++ ) для Watcom C/C++ в QNX4

Пробую так:
...
int IDMA_ADDRESS_REG = 0x300;
int IDMA_DATA_REG = 0x302;
short pBuffer[1024];

asm(
   "push    di" ;
   "cld" ;
   "mov   ax, 2000H" ;
   "mov   dx, IDMA_ADDRESS_REG";
   "out   dx, ax";
   "les   di, pBuffer";
   "mov   cx, 1024";
   "mov   dx, IDMA_DATA_REG";
   "repe   insw";
   "pop   di"
       );

При компиляции получаю

Warning ! W010:(col ** ) asm directive ignored

Как сделать правильно?
Спасибо.

P.S.
цель asm-вставки - ускорить вычитывание данных из буфера устройства при приходе прерывания.
Сейчас 1024 раза за одно перывание делается inpw(IDMA_DATA_REG), была надежда что "repe   insw" ускорит это действие.

Пока сделан тест на базе asm1.c  и asm.S ( asm.rar во вложении).
Вроде получается так, что выигрыша по времени не получилось, а хотелось бы.

Так же не получилось переименовать asm1.c в asm1.cc и собрать тест с использованием wpp. Видимо wcc и wpp что-то делают
с именами констант и функций по-разному.

спасибо.
Записан
Олег Большаков
Администратор
Житель форума

Сообщений: 2929



WWW
« Ответ #1 : 12 Августа, 2011, 11:31:55 »

Ассемблерные вставки в Watcom C делаются немного иначе, например:

Код:
void read_mem(void);
#pragma aux read_mem = \
   "push    di" \
   "cld" \
   "mov   ax, 2000H" \
   "mov   dx, IDMA_ADDRESS_REG" \
   "out   dx, ax" \
   "les   di, pBuffer" \
   "mov   cx, 1024" \
   "mov   dx, IDMA_DATA_REG" \
   "repe   insw" \
   "pop   di" \
   modify [ax bx cx dx di es];

Более подробно о директиве pragma можно почитать в документации на компилятор.


Действительно, компиляторы C и C++ (не только wcc и wpp) по-разному формируют имена переменных и функций. Чтобы "переименовать" asm1.c в asm1.cc надо обрамить объявление переменных и функций следующей конструкцией:

Код:
extern "C" {

}

Т.е. Ваш код будет выглядеть примерно так:

Код:
extern "C" {
extern short pBuffer[1024];

short DATA_REG, *ptrB;

void asm_funct();
}


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


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

Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP © 2002-2016 СВД Встраиваемые Системы.
При использовании материалов сайта ссылка на forum.kpda.ru обязательна.

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines | © Aiwan. Kolobok smiles | Sitemap
Valid XHTML 1.0! Valid CSS!
Сайт СВД ВС

В последний раз google посещал эту страницу 01 Ноября, 2016, 19:38:19