реклама на сайте
подробности

 
 
> Использование ассемблера в MinGW, вопросики...
Виктория
сообщение Aug 27 2009, 07:52
Сообщение #1


инженер
****

Группа: Свой
Сообщений: 520
Регистрация: 19-09-05
Из: Самара
Пользователь №: 8 701



Осваиваем инлайновский ассемблер в MinGW.
Текст функции
Код
/******* Вывод байта в порт *******/
void outportb(unsigned addr,        // адрес регистра
                      unsigned char data)    // данные для записи
{
      asm(“mov %%eax, %2; \        // шаблон кода на ассемблере для
               out %1, %%al;”          // вывода байта в порт
               :                    // выходных переменных нет
               : “r” (addr), “r” (data)        // список входных операндов
               : “%%eax”, “%%al”);        // используемые регистры
}


1) Компилятор не желает передавать параметры через короткие регистры, даже для unsigned char (кто-нибудь знает какая, кстати, у него длина в Минималисте?). Поэтому используем eax.

2) Компилятор ругается на строчку с out (неправильный суффикс или операнд?), причём ругается именно на al (т.е. при замене out на mov - одно и тоже сообщение об ошибке). Непонятно sad.gif

3) Тип void тоже почему-то не понимает... Придется вводить фиктивную выходную переменную типа int, например.

Плиз, помогите. Может у кого-нибудь были похожие ситуации и в другом gcc (не обязательно под Windows, для любого МК)? Передать, естеств., хотелось бы байт. Т.к. это для учебной лабы.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ReAl
сообщение Aug 27 2009, 12:01
Сообщение #2


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Фрагмент кода avreal
компилируется (и работает wink.gif ) gcc - linux, freebsd, mingw32
base - это приватное поле класса, базовый адрес LPT
*_offset - enum-ы на разрешённые для операции регистры LPT
Код
uint8_t
lpt_io_t::read(rd_offset offs) const
{
    uint8_t value;
    __asm__ __volatile__(
        "inb %w1, %0"
        : "=a"(value)
        : "Nd"(base_ + offs)
    );
    return value;
}

void
lpt_io_t::write(wr_offset offs, uint8_t value) const
{
    __asm__ __volatile__(
        "outb %b0, %w1"
        :
        : "a"(value), "Nd"(base_ + offs)
    );
}

void
lpt_io_t::write_data(const uint8_t * buf, int len) const
{
    __asm__ __volatile__(
        "cld" "\n\t"
        "rep outsb"
        : "+S"(buf), "+c"(len)
        : "d"(base_)
    );
}

Для нескольких команд команды надо разделять "\n\t", так как и без '\' всё равно всё сольётся в одну длинную строку средствами С-компилятора ещё до передачи в обработку __asm__
Для in/out адрес должен быть именно в dx - в словном, поэтому казывается %w1 а не %1


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 20:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.01386 секунд с 7
ELECTRONIX ©2004-2016