Друзья! кто знает CubeIDE ?.. как можно обратиться в ассемблере к переменной определенной в си?... Я вставляю куски программ написанные построчно на ассемблере в си файлы. Приходится после компиляции программы смотреть в файле xxxx.map адрес переменной, куда ее расположил линк, и вставлять в ассемблерный код. И всякий раз после изменения программы, если добавляются переменные, линк по другому располагает их в памяти и приходится снова смотреть xxxx.map и снова корректировать в ассемблере место где обращение к этой переменной. Кто знает как обратиться к переменной определенной в си, из inline ассемблера?
Доброго времени суток! Так должно работать:
uint32_t myVariable = 0; __asm volatile("MSR PSPLIM, %0" :: "r" (myVariable));
@aveal Спасибо! Сделал но не работает. Чтобы обратиться к переменной определенной в си из ассемблера необходимы две строки, поскольку 32-битное слово прямой загрузкой в рабочий регистр можно осуществить только двумя инструкциями:
int32_t U_sr_av;
__asm( " MOV R0, #0x0248 " ); // загрузить в R0 младшие 16 бит адреса
__asm( " MOVT R0, #0x2000 " ); // загрузить в R0 старшие 16 бит адреса
__asm( " LDRH R3, [R0,#0] " ); // теперь загружаем в R3 переменную по адресу R0 с смещением ноль
Bместо числа #20000248 необходимо как-то вставить имя переменной которая определена в си, допустим U_sr_av.
Я работаю в STM32CubIDE
@eduard-3 Приветствую! Так, а если такой вариант, навскидку:
uint32_t u32Value = 0x11223344; __asm("LDR R3, %0 " :: "m" (u32Value));
@aveal Это что-то не то. В смотрите пример:
uint32_t U_sr; // определил переменную в си
__asm( " ADR R4,#U_sr" ); // загрузить в R4 адрес переменной U_sr. здесь компилятор дает ошибку он не понимает записи #U_sr ни &U_sr ни _U_sr
__asm( " LDR R3, [R4,#0] " ); // загрузить в R3 значение находящуюся по адресу в R4
Вопрос: Как объявить переменную U_sr ,чтобы компилятор увидел метку U_sr в ассемблерной строке? Или может быть в ассемблере эту метку объявить так чтобы доступ к ней был и из ассемблера и из си?
@eduard-3 Ну вот, объявил переменную в C:
uint32_t u32Value = 0x11223344;
Поместил ее значение в R3:
__asm("LDR R3, %0 " :: "m" (u32Value));
В R3 значение 0x11223344, адрес не нужен.
Если из принципиальных соображений надо сделать через адрес, то же самое:
uint32_t u32Value = 0x11223344; uint32_t* address = &u32Value; __asm("LDR R4, %0 " :: "m" (address)); __asm("LDR R3, [R4, #0]");
@aveal Конечно это не принципиально каким способом из двух последних что Вы предложили, но первый транслируется ассемблером в две инструкции а второй в три. Ваш ответ заработал, я проверил по листингу первый предложенный вариант, ассемблер вставил правильно адрес переменной. Спасибо Вам большое!!! Но где все эти премудрости, про смешанное программирование , можно прочитать чтобы не мыкаться впредь? Еще раз огромное спасибо!!!
@eduard-3 Доброго времени!
Пропустил последнее сообщение, только увидел. Самый надежный вариант - в исходниках поиском найти ассемблерные вставки (в файлах HAL или CMSIS, например), там по сути можно реальные примеры использования увидеть.