Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Положение поля в классе
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Ivan.
Как получить Offset поля в классе?
Впринципе это вопрос общего назначения, но для уточнения, я пишу под WinAVR.
При применении ассемблерных вставок в C++ для работы со структурами появляется необходимость взятия переменной относительно какого-то объекта (указателя), например:
LDD R0, Y+OFFSET(T::i)
Написал define:
#define OFFSETT(Type, Item) ((int)(&((Type *)0)->Item))
Что впринципе и возврящает необходимую константу. В С++ такой прикол проканывает, в асме старого компилятора тоже, а в новом начинает через один ворчать, мол не константа это.
Подскажите, может есть какие нибудь иные способы решения?
Сергей Борщ
Цитата(Ivan. @ Oct 9 2008, 08:48) *
#define OFFSETT(Type, Item) ((int)(&((Type *)0)->Item))
Что впринципе и возврящает необходимую константу. В С++ такой прикол проканывает, в асме старого компилятора тоже, а в новом начинает через один ворчать, мол не константа это.
надо посмотреть как в заголовочных файлах нового компилятора определен макрос offsetof(). Настораживает, что компилятор у вас ругается не на каждое выражение, а через одно. Может неспроста? Приведите пример, на который компилятор ругается.
ReAl
Цитата(Ivan. @ Oct 9 2008, 08:48) *
При применении ассемблерных вставок в C++
А чем не устраивает gcc-стандартное указание входных/выходных параметров в ассемблерной вставке
Код
class foo
{
  public:
    char a[4];
    uint8_t i, j;
};

void f(foo *p)
{
    __asm__ __volatile__ (
        "add %0, %1"
        : "+r" (p->i)
        : "r" (p->j)
    );
}


Код
.global    _Z1fP3foo
    .type    _Z1fP3foo, @function
_Z1fP3foo:
    movw r30,r24
    ldd r25,Z+5
    ldd r24,Z+4
/* #APP */
;  16 "c.cpp" 1
    add r24, r25
;  0 "" 2
/* #NOAPP */
    std Z+4,r24
    ret

Или в более сложных случаях эффективность падает?
Ivan.
Дефайна offsetof в WinAVR-е вообще нет, наверное его забыли. Но это не суть, впринцыпе я написал его-же.
Все хорошо, все правильно, но компилятор ругается, притом через раз. Вот пример:
Код
.....
    LDD(StatusO, Bus, offsetof(TMultiBus, StatusO));           //StatusO = Bus->StatusO;
    CPI(StatusO, soNone);                                      //if (StatusO != soNone)
    BREQ(TMultiBusRECV_NoColise);                              //{
        LDD(Echo, Bus, offsetof(TMultiBus, Echo));             //    Echo = Bus->Echo;
        CPSE(Echo, Byte);                                      //    if (Echo != Byte)
        LDI(StatusO, soNone);                                  //        StatusO = soNone;
        LDD(Echo, Bus, offsetof(TMultiBus, NextEcho));         //    Echo = Bus->NextEcho;
        STD(Bus, Echo, offsetof(TMultiBus, Echo));             //    Bus->Echo = Echo;
LABEL(TMultiBusRECV_NoColise);                                 //}
.....

Функции LDD, CPI, ... - это есть дефайны ассемблерных вставок, например:
Код
#define      LDD(Rd, Rb, K6) volatile asm("LDD    %0,  %a1+%2\n":"=r"(Rd)          :"e"(Rb), "I"(K6)) //Description: Load Indirect with displacement         |Operation: Rd = (Y+K6)                         |Flags: --------         |Cycles: 2

Компилятор выдает ошибки на строки 4 и 8 (именно те две строки, где используются два одинаковых offsetof(TMultiBus, Echo)), остальные строки проходят нормально.
error: impossible constraint in 'asm'

Вот я и хочу спросить, есть ли какие нибудь другие варианты?
demiurg_spb
Цитата(Ivan. @ Oct 15 2008, 10:13) *
Дефайна offsetof в WinAVR-е вообще нет, наверное его забыли. Но это не суть, впринцыпе я написал его-же.

Это как сказатьsmile.gif
Цитата
5.46 Offsetof

GCC implements for both C and C++ a syntactic extension to implement the offsetof macro.

primary:
"__builtin_offsetof" "(" typename "," offsetof_member_designator ")"

offsetof_member_designator:
identifier
| offsetof_member_designator "." identifier
| offsetof_member_designator "[" expr "]"

This extension is sufficient such that

#define offsetof(type, member) __builtin_offsetof (type, member)

is a suitable definition of the offsetof macro. In C++, type may be dependent. In either case, member may consist of a single identifier, or a sequence of member accesses and array references.

Изучите файлик stddef.h
aesok
Цитата(Ivan. @ Oct 15 2008, 10:13) *
Компилятор выдает ошибки на строки 4 и 8 (именно те две строки, где используются два одинаковых offsetof(TMultiBus, Echo)), остальные строки проходят нормально.
error: impossible constraint in 'asm'

Вот я и хочу спросить, есть ли какие нибудь другие варианты?


Какое смещение до поля Echo?

Анатолий.
Сергей Борщ
Цитата(Ivan. @ Oct 15 2008, 09:13) *
Все хорошо, все правильно, но компилятор ругается, притом через раз. Вот пример:
error: impossible constraint in 'asm'
Вот с этого и надо было начинать. В ошибке ведь все сказано. Идете в c:/WinAVR/DOC/avr-libc/avr-libc-user-manual, находите там руководство по inline-ассемблеру, и в нем видите, что с инструкцией ldd должны использоваться констранты (это как-то переводится?) r и b, а не r и e, как у вас.
IgorKossak
Цитата(Сергей Борщ @ Oct 15 2008, 11:49) *
... констранты (это как-то переводится?) ...

Переводится так:
Цитата
1) принуждение; оказывание давления (на кого-л., что-л.)
- under constraint
- impose a constraint
- place a constraint
- put a constraint
- legal constraints
2)
а) принужденность; стеснение; стеснительность
б) напряженность; скованность, неестественность
- show constraint
Syn:
tensity, tenseness
3) тюремное заключение
Syn:
imprisonment

А вот как это выглядит в контексте сообщения ... wacko.gif
Сергей Борщ
Цитата(IgorKossak @ Oct 15 2008, 13:50) *
А вот как это выглядит в контексте сообщения ... wacko.gif
"Ограничитель"? Какой бы термин мы ни приняли, это будет наше сугубо внутреннее дело sad.gif Интересовало, есть ли общепринятый перевод для этого термина. Если нет - придется использовать без перевода.
defunct
Цитата(Сергей Борщ @ Oct 15 2008, 11:49) *
и в нем видите, что с инструкцией ldd должны использоваться констранты (это как-то переводится?) r и b, а не r и e, как у вас.

Переводится как на инструкцию LDD накладываются ограничения dest - r, src - base pointer y, z.

Что кстати весьма странно, ведь эта инструкция может работать и с x регистром.
aesok
Цитата(defunct @ Oct 15 2008, 21:52) *
Переводится как на инструкцию LDD накладываются ограничения dest - r, src - base pointer y, z.

Что кстати весьма странно, ведь эта инструкция может работать и с x регистром.


Не может, нет инструкции LDD Rd, X+q; есть только LD Rd, [-]X[+]

Цитата(Ivan. @ Oct 15 2008, 10:13) *
Код
#define      LDD(Rd, Rb, K6) volatile asm("LDD    %0,  %a1+%2\n":"=r"(Rd)          :"e"(Rb), "I"(K6)) //Description: Load Indirect with displacement         |Operation: Rd = (Y+K6)                         |Flags: --------         |Cycles: 2

Компилятор выдает ошибки на строки 4 и 8 (именно те две строки, где используются два одинаковых offsetof(TMultiBus, Echo)), остальные строки проходят нормально.
error: impossible constraint in 'asm'

Вот я и хочу спросить, есть ли какие нибудь другие варианты?


Я не экстрасенс, а автор не привел описание структуры (класа?) TMultiBus но все же рискну погадать.

Скорее всего структура довольно большая и offsetof(TMultiBus, Echo) больше 63, что больше ограничения накладываемого constraint "I" (константа от 0 до 63). На что и ругается компилятор.

Анатолий.
Ivan.
Огромное спасибо за такую поддержку, но пока это все косвенные причины, каторые можно опровергнуть:
1:
Цитата
ldd должны использоваться констранты (это как-то переводится?) r и b, а не r и e, как у вас.
Да я согласен, что я здесь ошибся определив переменную-указатель в e а не в b, но переменная уже лежит в регистре Y, да и другие команды-то компилируются. (Подправлю, но это не то).
2:
Цитата
Скорее всего структура довольно большая и offsetof(TMultiBus, Echo) больше 63, что больше ограничения накладываемого constraint "I" (константа от 0 до 63).
Нет структура довольно маленькая и смещение равно 18.

И третье: если закоментарить 8 строку в приведенном отрывке, то и 4 строка компилируется нормально. А если далее по тексту написать
STD(Bus, StatusO, offsetof(TMultiBus, StatusO)); //Bus->StatusO = StatusO;
то компилятор начинает ворчать на 1 строку и на новую.
defunct
Ivan
Сорри за нескромный вопрос. Для чего Вы хотите смешать C++ с asm? Ведь от этого только переносимость и читаемость кода пострадает. Выигрышь в производительности весьма сомнительный.
demiurg_spb
Цитата(defunct @ Oct 20 2008, 19:14) *
Ivan
Сорри за нескромный вопрос. Для чего Вы хотите смешать C++ с asm? Ведь от этого только переносимость и читаемость кода пострадает. Выигрышь в производительности весьма сомнительный.


Тем более это странно, после того, как я показал, что макрос offsetof уже есть в stddef.h
Его можно изучить поглядев на stddef.h из MS Visual Studio или C-builder.
Ivan.
Цитата
Сорри за нескромный вопрос. Для чего Вы хотите смешать C++ с asm? Ведь от этого только переносимость и читаемость кода пострадает. Выигрышь в производительности весьма сомнительный.
Согласен, совместимость и читабельность ухудьшается, а выигрыш довольно большой. Даже если взять текуший отлаженный, вылизанный ассемблерный код и перевести его на С/С++ диву даешься, что компилятор вытваряет, сердце кровью обливается. Я тут такты экономлю, а он такой код раздувает.
Задача, каторую я решаю - это протокол на основе RS485 интерфейса работающий на скорости 115200.
Это давольно умный протокол в катором все устройства являются главными и могут говорить в любой момент кому угодно. Для таких возможностей появляется необходимость выявления занятости линии и определения кализий на линии. Каждый контроллер должен успевать, по приему каждого байта, определять кому, от кого летит пакет, подсчитывать контрольную сумму и так далее.
А теперь представим, что у главного контроллера есть два таких интерфейса, и по обоим летят пакеты и все это нужно успеть при тактовой чистоте 14МГц. При старой организации на С, в самых сложных случаях (когда контроллер передает в оба интерфейса одновременно, а значит и принимает для определения кализий) это занимало 2/3 процессорного времени, а сейчас 1/3. Объем кода снижен с 5К до 2К, а для atmega8 это существенно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.