|
|
  |
Положение поля в классе |
|
|
|
Oct 9 2008, 05:48
|

Группа: Участник
Сообщений: 7
Регистрация: 13-02-07
Пользователь №: 25 325

|
Как получить Offset поля в классе? Впринципе это вопрос общего назначения, но для уточнения, я пишу под WinAVR. При применении ассемблерных вставок в C++ для работы со структурами появляется необходимость взятия переменной относительно какого-то объекта (указателя), например: LDD R0, Y+OFFSET(T::i) Написал define: #define OFFSETT(Type, Item) ((int)(&((Type *)0)->Item)) Что впринципе и возврящает необходимую константу. В С++ такой прикол проканывает, в асме старого компилятора тоже, а в новом начинает через один ворчать, мол не константа это. Подскажите, может есть какие нибудь иные способы решения?
--------------------
Я могу ВСЁ, вопрос, сколько времени у меня это займет.
|
|
|
|
|
Oct 9 2008, 06:46
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Ivan. @ Oct 9 2008, 08:48)  #define OFFSETT(Type, Item) ((int)(&((Type *)0)->Item)) Что впринципе и возврящает необходимую константу. В С++ такой прикол проканывает, в асме старого компилятора тоже, а в новом начинает через один ворчать, мол не константа это. надо посмотреть как в заголовочных файлах нового компилятора определен макрос offsetof(). Настораживает, что компилятор у вас ругается не на каждое выражение, а через одно. Может неспроста? Приведите пример, на который компилятор ругается.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 9 2008, 09:05
|

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

|
Цитата(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 Или в более сложных случаях эффективность падает?
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Oct 15 2008, 06:13
|

Группа: Участник
Сообщений: 7
Регистрация: 13-02-07
Пользователь №: 25 325

|
Дефайна 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' Вот я и хочу спросить, есть ли какие нибудь другие варианты?
--------------------
Я могу ВСЁ, вопрос, сколько времени у меня это займет.
|
|
|
|
|
Oct 15 2008, 07:40
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(Ivan. @ Oct 15 2008, 10:13)  Дефайна offsetof в WinAVR-е вообще нет, наверное его забыли. Но это не суть, впринцыпе я написал его-же. Это как сказать  Цитата 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
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Oct 15 2008, 08:49
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Ivan. @ Oct 15 2008, 10:13)  Компилятор выдает ошибки на строки 4 и 8 (именно те две строки, где используются два одинаковых offsetof(TMultiBus, Echo)), остальные строки проходят нормально. error: impossible constraint in 'asm'
Вот я и хочу спросить, есть ли какие нибудь другие варианты? Какое смещение до поля Echo? Анатолий.
|
|
|
|
|
Oct 15 2008, 08:49
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(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, как у вас.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 15 2008, 19:56
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(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). На что и ругается компилятор. Анатолий.
Сообщение отредактировал aesok - Oct 15 2008, 20:09
|
|
|
|
|
Oct 20 2008, 05:18
|

Группа: Участник
Сообщений: 7
Регистрация: 13-02-07
Пользователь №: 25 325

|
Огромное спасибо за такую поддержку, но пока это все косвенные причины, каторые можно опровергнуть: 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 строку и на новую.
--------------------
Я могу ВСЁ, вопрос, сколько времени у меня это займет.
|
|
|
|
|
Oct 28 2008, 07:06
|

Группа: Участник
Сообщений: 7
Регистрация: 13-02-07
Пользователь №: 25 325

|
Цитата Сорри за нескромный вопрос. Для чего Вы хотите смешать C++ с asm? Ведь от этого только переносимость и читаемость кода пострадает. Выигрышь в производительности весьма сомнительный. Согласен, совместимость и читабельность ухудьшается, а выигрыш довольно большой. Даже если взять текуший отлаженный, вылизанный ассемблерный код и перевести его на С/С++ диву даешься, что компилятор вытваряет, сердце кровью обливается. Я тут такты экономлю, а он такой код раздувает. Задача, каторую я решаю - это протокол на основе RS485 интерфейса работающий на скорости 115200. Это давольно умный протокол в катором все устройства являются главными и могут говорить в любой момент кому угодно. Для таких возможностей появляется необходимость выявления занятости линии и определения кализий на линии. Каждый контроллер должен успевать, по приему каждого байта, определять кому, от кого летит пакет, подсчитывать контрольную сумму и так далее. А теперь представим, что у главного контроллера есть два таких интерфейса, и по обоим летят пакеты и все это нужно успеть при тактовой чистоте 14МГц. При старой организации на С, в самых сложных случаях (когда контроллер передает в оба интерфейса одновременно, а значит и принимает для определения кализий) это занимало 2/3 процессорного времени, а сейчас 1/3. Объем кода снижен с 5К до 2К, а для atmega8 это существенно.
--------------------
Я могу ВСЁ, вопрос, сколько времени у меня это займет.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|