Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

gcc 4.2.4: Как отменить оптимизацию функции ?

5.9K
08 марта 2012 года
assign
60 / / 13.12.2005
Здравствуйте, товарищи!
Вопрос такой:
Есть функция:

Код:
PUBLIC WORD tty_getpos(void)
/*
 Возвращает текущую позицию курсора.
 Эта функция обращается к регистрам
 контроллера ЭЛТ.
*/

{
    BYTE l, h;

    __outb(POS_REG, CRT_PORT);
    h = __inb(CRT_PORT + 1);
    __outb((POS_REG + 1), CRT_PORT);
    l = __inb(CRT_PORT + 1);

    return ((h<<8) + l);
}


Пусть Вас не смущают все эти BYTE, WORD и PUBLIC - это мои типы, они объявлены в h-файле, дело не в этом... Проблема в функциях __inb() и outb(). Данные функции объявлены в заголовке asm.h как static inline и с ними получается ерунда: при любом уровне оптимизацииб большем или равном 1 компилятор совершенно искажает код и в результате функция tty_getpos возвращает совсем не то, что надо. Если оптимизацию совсем отключить, то tty_getpos возвращает правильный результат, но теряется вся прелесть inline-функций - они становятся обычными функциями. Так вот вопрос: а нельзя ли gcc дать какой-нибудь ключик, или прагму, чтобы он оптимизацию в целом выполнил, а туда куда мне не надо не лез?

Спасибо!
  • Код asm.h с вашими inb/outb, а так же то, что вас не устраивает на выходе компилятора в дизассемблере в студию. от Ramon, 08 марта 2012 года
4
08 марта 2012 года
mike
3.7K / / 01.10.2002
Используй pragma pack
Код:
/*
Возвращает текущую позицию курсора.
Эта функция обращается к регистрам
контроллера ЭЛТ.
*/


PUBLIC WORD tty_getpos(void) {
    BYTE l, h;

    #pragma pack(0)
    __outb(POS_REG, CRT_PORT);
    h = __inb(CRT_PORT + 1);
    __outb((POS_REG + 1), CRT_PORT);
    l = __inb(CRT_PORT + 1);
    #pragma pack()

    return ((h<<8) + l);
    }

316
08 марта 2012 года
Alm3n
889 / / 29.05.2009
Цитата: mike
Используй pragma pack
Код:
/*
Возвращает текущую позицию курсора.
Эта функция обращается к регистрам
контроллера ЭЛТ.
*/


PUBLIC WORD tty_getpos(void) {
    BYTE l, h;

    #pragma pack(0)
    __outb(POS_REG, CRT_PORT);
    h = __inb(CRT_PORT + 1);
    __outb((POS_REG + 1), CRT_PORT);
    l = __inb(CRT_PORT + 1);
    #pragma pack()

    return ((h<<8) + l);
    }


Какая связь между выравниванием данных и inline-функциями?
2 Topic starter
Читал, что все методы класса, реализованные в заголовках, становятся inline вне зависимости от того, был ли этот спецификатор. Можно поэкспериментировать на эту тему.

5.9K
09 марта 2012 года
assign
60 / / 13.12.2005
Сам дошёл методом научного тыка.
Оказыватся надо было употребить волшебное словечко __volatile__.
Вот мой файл asm.h:


Код:
#undef _ASSEMBLER_

#ifndef __ASM_H__
#define __ASM_H__

#include <defs.h>

INLINE BYTE __inb(WORD port)
{
    BYTE result;
    __asm__ __volatile__ (
        "inb      %w1, %b0\n" : "=a"(result) : "d"(port)
    );
    return result;
}

INLINE VOID __outb(BYTE val, WORD port)
{
    __asm__ __volatile__ (
        "outb     %b0, %w1\n" : : "a"(val), "d"(port)
    );
}

#endif



Все неприятности были от того, что не было слова __volatile__ в операторе __asm__.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог