|
|
  |
Коды завершения функции |
|
|
|
Apr 25 2018, 08:25
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(jcxz @ Apr 25 2018, 10:41)  Если не умеете читать и понимать даже выдержки из даташита - Ваши проблемы. Может приведёте какие-то аргументы? Я аргументы привёл, от Вас - только трёп.  О том, что компилятор IAR (for ARM) позволяет использовать для возвращаемых значений до двух регистров (R0,R1). Если кто-то знает другое (или про компилятор использующий большее число регистров) - плиз приведите аргументы. Цитата 5.4 Result Return The manner in which a result is returned from a function is determined by the type of that result. For the base standard: A Half-precision Floating Point Type is converted to single precision and returned in r0. A Fundamental Data Type that is smaller than 4 bytes is zero- or sign-extended to a word and returned in r0. A word-sized Fundamental Data Type (e.g., int, float) is returned in r0. A double-word sized Fundamental Data Type (e.g., long long, double and 64-bit containerized vectors) is returned in r0 and r1. A 128-bit containerized vector is returned in r0-r3. A Composite Type not larger than 4 bytes is returned in r0. The format is as if the result had been stored in memory at a word-aligned address and then loaded into r0 with an LDR instruction. Any bits in r0 that lie outside the bounds of the result have unspecified values. A Composite Type larger than 4 bytes, or whose size cannot be determined statically by both caller and callee, is stored in memory at an address passed as an extra argument when the function was called (§5.5, rule A.4). The memory to be used for the result may be modified at any point during the function call.
|
|
|
|
|
Apr 25 2018, 08:38
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
И откуда сиё взято? В "IAR C/C++ Development Guide" поиск даже просто любого из слов "containerized" или "128-bit" - Not found. Цитата(Kabdim @ Apr 25 2018, 10:58)  Вряд ли эта ОЗУ вся забита кодом, т.е. реально упаковать код ошибки + pc в 32битное слово, или +lr и возвращать 64 бита. Не понятна эта фраза. Вы предлагаете к адресу возврата прибавлять некое число, которое и является результатом? Тогда после каждой точки вызова этой функции придётся располагать таблицу из N*2 инструкций B (где N - максимальное возвращаемое значение). И на си такое будет сложно проделать.
|
|
|
|
|
Apr 25 2018, 08:51
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
QUOTE (jcxz @ Apr 25 2018, 15:41)  Если кто-то знает другое (или про компилятор использующий большее число регистров) - плиз приведите аргументы. Я вообще никогда не задумывался над этим. Возвращал стурктуры, и всё. Методами класса. Т.к. использую Си++, но это наверно сути не меняет. Возвращал структуры до 100 байт размером. Думаю, что если есть ограничение, компилятор какую-то подстановку выполняет. Но разве это имеет значение? QUOTE (Kabdim @ Apr 25 2018, 15:58)  Вряд ли эта ОЗУ вся забита кодом, т.е. реально упаковать код ошибки + pc в 32битное слово, или +lr и возвращать 64 бита. По-прежнему не понимаю вас) Вот пример возвращаемой структуры: CODE typedef struct FuncResult { CodeResult result; uint32_t lrReg; uint32_t pcReg; }; Правильно?
--------------------
Выбор.
|
|
|
|
|
Apr 25 2018, 08:55
|
Знающий
   
Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842

|
Цитата(jcxz @ Apr 25 2018, 11:38)  Не понятна эта фраза.  Просто битовая упаковка структуры. Цитата(haker_fox @ Apr 25 2018, 11:51)  По-прежнему не понимаю вас) Вот пример возвращаемой структуры: Код typedef struct FuncResult { CodeResult result; uint32_t lrReg; uint32_t pcReg; }; Правильно? В стартовом варианте, до уапковки - да. Только я бы добавил еще bool для детектирование ошибка/без ошибок. Без ошибки значения структуры нужно использовать для возвращения собственно результата. Т.е. скорее Код template<class T, class E>struct Result { bool is_valid; union { T t; struct { E e; uint32_t lrReg; uint32_t pcReg; } } }
|
|
|
|
|
Apr 25 2018, 09:00
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ Apr 25 2018, 11:42)  Я, правда, процитировал предыдущую версию. Там есть небольшое отличие, для данной темы несущественное. И что? Я разве отрицал, что возможно возвращать более чем два регистра? Да, раз R0-R3, R12 - scratch registers, то (согласно логике) можно хоть все их использовать для return. Но мне неизвестен такой компилятор, который так делает. Про него и спрашивал. Вам такой известен? Цитата(haker_fox @ Apr 25 2018, 11:51)  Я вообще никогда не задумывался над этим. Возвращал стурктуры, и всё. Методами класса. Т.к. использую Си++, но это наверно сути не меняет. Возвращал структуры до 100 байт размером. Думаю, что если есть ограничение, компилятор какую-то подстановку выполняет. Но разве это имеет значение? А следует задумываться. Конечно имеет. Такой возврат будет выполняться на стеке. И это место на стеке выделяется вызывающим кодом. В точке вызова. Соответственно - в стеке должно быть достаточно места.
|
|
|
|
|
Apr 25 2018, 09:06
|
Знающий
   
Группа: Участник
Сообщений: 916
Регистрация: 3-10-08
Из: Москва
Пользователь №: 40 664

|
Цитата Думаю, что если есть ограничение, компилятор какую-то подстановку выполняет. Но разве это имеет значение? Ну, значение, находящееся в регистрах можно использовать сразу же. Значение, которое сначала сохраняется в память, а потом из неё читается в регистры, чтобы его можно было использовать - запускает как минимум 2 операции работы с памятью, что гораздо медленее, особенно, если у вашей машины нет кэша. Операции с памятью, они, вообще, достаточно дорогие в плане производительности. А, возвращаясь к первоначальному вопросу - возвращению кода ошибки... 2^800 кодов ошибок - это уже слишком  В этом случае лучше вернуть наличие/отсутствие ошибки через регистр, а остальное поместить в память, и пусть оно (остальное) считывается, только если нужно.
Сообщение отредактировал one_eight_seven - Apr 25 2018, 09:08
|
|
|
|
|
Apr 25 2018, 09:14
|
Знающий
   
Группа: Участник
Сообщений: 916
Регистрация: 3-10-08
Из: Москва
Пользователь №: 40 664

|
Цитата Всё универсальное - неоптимально по определению и годится только для быдлокодерства в ардуино-стиле. А если не "универсальное", а "унифицированное"?
|
|
|
|
|
Apr 25 2018, 09:20
|

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

|
QUOTE (haker_fox @ Apr 25 2018, 10:51)  Вот пример возвращаемой структуры: CODE typedef struct FuncResult { CodeResult result; uint32_t lrReg; uint32_t pcReg; }; Правильно? Неаккуратненько  Должно быть как минимум так: CODE typedef struct FuncResult { CodeResult result; uintptr_t lrReg; uintptr_t pcReg; };
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|