|
Embedded assembler syntax in C, Как создать внутри кода на Си участок из ассемблерного кода |
|
|
|
Mar 12 2018, 07:35
|
Участник
Группа: Участник
Сообщений: 67
Регистрация: 17-06-12
Пользователь №: 72 370
|
Доброго времени суток! Прошу подсказать или показать пример, как создать в коде на Си участок из ассемблерного кода (пишу критическую секцию и важно быть уверенным во времени исполнения участка). Нужно ли подключать какие-либо библиотеки и проводить дополнительные настройки? Пример на сайте ARM видел. Я пытался скопировать его. Компилятор понимает директивы, но команды ассемблера не понимает. Спасибо!
|
|
|
|
|
Mar 12 2018, 11:04
|
Просто Che
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881
|
По ссылке на сайте АРМ, там руководство по использованию их ассемблера, это немного не то. Если вы пишете под Кейлом, то изучайте руководство на Кейл. Напр. у ИАРа все подробно расписано.
А по технологии, применяют или отдельные файлы на ассме, куда помещают функции, написанные согласно соглашениям о вызовах данного компилятора, или ассемблерные вставки прямо в тексте Си. Все должно быть описано в руководстве на компилятор.
Если куски ассма большие, лучше в файлы, т.к. вставки ассма в Си плохо воспринимают оптимизаторы компиляторов.
|
|
|
|
|
Mar 12 2018, 13:18
|
Участник
Группа: Участник
Сообщений: 67
Регистрация: 17-06-12
Пользователь №: 72 370
|
Господа, спасибо за ответы! Почитал кейловский мануал и решил написать простую функцию: Код __asm void test(int i){ } Компилятор ругается на "void"
|
|
|
|
|
Mar 12 2018, 13:39
|
Участник
Группа: Участник
Сообщений: 67
Регистрация: 17-06-12
Пользователь №: 72 370
|
Цитата(ViKo @ Mar 12 2018, 16:31) Не обращайте внимания. Это не компилятор, и не на void. Понял, спасибо! В ближайшее время опробую и отпишусь!
|
|
|
|
|
Mar 13 2018, 04:13
|
Универсальный солдатик
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362
|
Цитата(jcxz @ Mar 12 2018, 21:12) Никак. Но и смешивать си-код и асм, не зная какие регистры и как использует первый - чревато. Вот Вы написали "BX LR", а ведь в LR в конце функции не обязательно будет адрес возврата, если пролог функции "написал" си-компилятор. Какой пролог? Вся функция показана. Название в том числе. Умный компилятор Кейла (полагаю, как и другие) считает R0, R1 и т.п. не названиями регистров, а именами переменных. Да, Кейл, естественно, выполняет соглашение о порядке передачи аргументов в функцию.
|
|
|
|
|
Mar 13 2018, 12:59
|
Гуру
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713
|
Цитата(ViKo @ Mar 13 2018, 06:13) Какой пролог? Вся функция показана. Название в том числе. Если это и есть вся функция, то нафига её писать в си-файле??? Для этого существуют асм-файлы. Про пролог сказано для случая смешивания си-кода и асм-кода в одной функции как хочет автор. Читайте внимательнее. "Пролог" - это набор инструкций, который вставляется компилятором (си) в начало функции. Это может быть PUSH ..., может быть PUSH ...;SUB SP,..., могут быть пересылки аргументов в другие регистры или ещё чего - зависит от содержимого функции. К ассемблеру отношения не имеет.
|
|
|
|
|
Mar 13 2018, 13:25
|
Универсальный солдатик
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362
|
Поначалу функцию имел следующую: Код __asm void HardFault_Handler(void) { TST LR, #4 ITE EQ MRSEQ R0, MSP ; Main Stack was used, put MSP in R0 MRSNE R0, PSP ; Process Stack was used, put PSP in R0 LDR R0, [R0, #24] ; Get stacked PC from stack LDR R1, =0x40020418 ; GPIOB->BSRR MOVS R2, #0x0002 ; Bit 2 STRH R2, [R1, #2] ; Reset bit (LED_ON) B . } Здесь без ассемблера не обойтись. Потом упростил. Не пробовал писать ее на С. Думаю, такой простоты на С не получится.
|
|
|
|
|
Mar 13 2018, 13:43
|
Гуру
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713
|
Цитата(ViKo @ Mar 13 2018, 15:25) Поначалу функцию имел следующую: __asm void HardFault_Handler(void) Ну - у меня тоже обработчик fault-ов на асм написан. Только он в несколько десятков раз больше. Защёлкивает содержимое всех важных регистров, кадра стека, разной информации о fault-е и сохраняет в структуру в памяти. И расположен он в асм-файле. А потом оттуда - переход на си-функцию, которая эту всю инфу уже использует (выплёвывает в UART в аналог "синего окна смерти" или пишет в журнал событий и перегружает МК). А вот атомарные операции с эксклюзивным доступом я написал на си, с помощью intrinsic-функций, типа (атомарная операция "сравнение и обмен"): Код inline u32 AtomicCmpSwp(u32 volatile *ptr, u32 newVal, u32 cmpVal) { u32 i, i1; do { i = __LDREX(ptr); if (i == cmpVal) i1 = __STREX(newVal, ptr); } while (i == cmpVal && i1 == 1); return i; } Аналог виндовой InterlockedCompareExchange()... PS: Если автору "важно быть уверенным во времени исполнения участка" - нужно для минимизации времени запрета прерываний внутри критической секции, то использование подобных операций эксклюзивного доступа даёт возможность обойтись вообще без запретов прерывания. Если уж так хочется.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|