Top.Mail.Ru
Уведомления
Очистить все

Программирование на ассемблере в файлах си

(@eduard-3)
Level 1

Друзья! кто знает CubeIDE ?.. как можно обратиться в ассемблере к переменной определенной в си?...    Я вставляю куски программ написанные построчно на ассемблере в си файлы. Приходится после компиляции программы смотреть в файле xxxx.map адрес переменной, куда ее расположил линк, и вставлять в ассемблерный код. И всякий раз после изменения программы, если добавляются переменные, линк по другому располагает их в памяти и приходится снова смотреть xxxx.map и снова корректировать в ассемблере место где обращение к этой переменной. Кто знает как обратиться к переменной определенной в си, из inline ассемблера?

 

Цитата
Создатель темы Размещено : 21.06.2024 09:07
Aveal
(@aveal)
Top level Admin

Доброго времени суток! Так должно работать:

uint32_t myVariable = 0;
__asm volatile("MSR   PSPLIM, %0" :: "r" (myVariable));
ОтветитьЦитата
Размещено : 21.06.2024 10:49
(@eduard-3)
Level 1

@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

ОтветитьЦитата
Создатель темы Размещено : 04.07.2024 09:49
Aveal
(@aveal)
Top level Admin

@eduard-3 Приветствую! Так, а если такой вариант, навскидку:

uint32_t u32Value = 0x11223344;
__asm("LDR R3, %0 " :: "m" (u32Value));
ОтветитьЦитата
Размещено : 04.07.2024 13:14
(@eduard-3)
Level 1

@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 в ассемблерной строке? Или может быть в ассемблере эту метку объявить так чтобы доступ к ней был и из ассемблера и из си?

ОтветитьЦитата
Создатель темы Размещено : 04.07.2024 14:54
Aveal
(@aveal)
Top level Admin

@eduard-3 Ну вот, объявил переменную в C:

uint32_t u32Value = 0x11223344;

Поместил ее значение в R3:

__asm("LDR R3, %0 " :: "m" (u32Value));

В R3 значение 0x11223344, адрес не нужен.

ОтветитьЦитата
Размещено : 04.07.2024 15:10
Aveal
(@aveal)
Top level Admin

Если из принципиальных соображений надо сделать через адрес, то же самое:

uint32_t u32Value = 0x11223344;
uint32_t* address = &u32Value;

__asm("LDR R4, %0 " :: "m" (address));
__asm("LDR R3, [R4, #0]");
изображение

 

ОтветитьЦитата
Размещено : 04.07.2024 15:20
(@eduard-3)
Level 1

@aveal  Конечно это не принципиально каким способом из двух последних что Вы предложили, но первый транслируется ассемблером в две инструкции а второй в три. Ваш ответ заработал, я проверил по листингу первый предложенный вариант, ассемблер вставил правильно адрес переменной. Спасибо Вам большое!!! Но где все эти премудрости, про смешанное программирование , можно прочитать чтобы не мыкаться впредь? Еще раз огромное спасибо!!!

ОтветитьЦитата
Создатель темы Размещено : 05.07.2024 11:28
Aveal
(@aveal)
Top level Admin

@eduard-3 Доброго времени!

Пропустил последнее сообщение, только увидел. Самый надежный вариант - в исходниках поиском найти ассемблерные вставки (в файлах HAL или CMSIS, например), там по сути можно реальные примеры использования увидеть.

ОтветитьЦитата
Размещено : 10.07.2024 10:34
Поделиться: