реклама на сайте
подробности

 
 
> Keil uVision 5 вставка ассемблера в C код., Функция на asm не возвращается в main.
Omnicake
сообщение Mar 31 2014, 10:56
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002



Здравствуйте, уважаемые. Пытаюсь научится правильно вставлять в код на C ассемблерные функции. Взял за основу пример с включением SysTick таймера на STM32f10x. Код программы такой:

CODE
#include "stm32f10x.h"
#define F_CPU 72000000UL //Частота процессора для таймера
#define TimerTick F_CPU/1000
void Delay(uint32_t Val);
extern int systick(void);

//SysTick Interrupt
void SysTick_Handler(void)
{
// Сюда вставляется событие при срабатывании прерывания.
}

int main(void)
{
SystemInit();
//Настройка процессора
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
GPIOB->CRL &= ~GPIO_CRL_CNF5;
GPIOB->CRL |= GPIO_CRL_MODE5_0;

systick(); //А это функция, которую я пытаюсь вставить

while(1)
{
}
}

Функция systick() имеет вид:

Код
    AREA HEAP, CODE, READONLY
    
systick        PROC
            EXPORT systick
            LDR    R0,[pc,#32]
            MOV    R1,#0xE000E000
            STR    R0,[r1,#0x14]
            STR    R0,[r1,#0x18]
            MOVS R0,#0x07
            STR    R0,[r1,#0x10]
            ENDP
            END

И представляет собой последовательность команд, которые выполнялись в дизассемблере ранее, когда таймер там вызывался через C-команды.
Проект компилируется без ошибок, но при пошаговом выполнении после команды END в systick, вываливается на HardFault_Handler, что, как я понимаю, не совсем здорово. Я предполагаю, что где-то накосячил с адресацией, но опять же, все брал из дизассемблерных команд, которые до этого нормально выполнялись. В чем моя ошибка?

Сообщение отредактировал IgorKossak - Mar 31 2014, 15:50
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 10)
kolobok0
сообщение Mar 31 2014, 11:39
Сообщение #2


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(Omnicake @ Mar 31 2014, 14:56) *
...но при пошаговом выполнении после команды END в systick, вываливается на HardFault_Handler...В чем моя ошибка?


ну наверное в том, что для ассемблера нет команды END(как инструкции для железа имеется ввиду).
Т.е. он продолжает и дальше выполнять следующие инструкции за данным адресом флэша.
наверное надо Вам поставить ретурн... если хотите возвратиться в то место откуда была вызвана даная функция.

Вообще совет дня типа:
Тупо напишите всё на сях. Подсматривайте потом компильнутый ассемблерный листинг. Многое узнаете нового. А! не забудьте оптимизацию
выставлять на максимум для этого сишнего кода - тогда азм получится лаконичней...


Сообщение отредактировал kolobok0 - Mar 31 2014, 11:40
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Mar 31 2014, 11:50
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а вы командой END чего добиться то хотели?
Go to the top of the page
 
+Quote Post
Omnicake
сообщение Mar 31 2014, 13:19
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002



Без END компилятор ругался на его отсутствие. Я считал что при выполнении END он выйдет из ассемблерной функции и продолжит выполнять C-код. Видимо, ошибался, спасибо за советы.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Mar 31 2014, 16:30
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



если речь идет о вставках, то они и должны быть вставками, нефиг функции делать. А вы прочитали как из функции выходить? Ведь надо восстановить: стэк, регистры, счетчик команд, и так далее и так далее... А всем этому должно предшествовать канетель с правильным сохранением этого всего перед входом.

вот
http://infocenter.arm.com/help/index.jsp?t...a/BABECGJD.html

это первоисточник, найдите там команду END....
Go to the top of the page
 
+Quote Post
toweroff
сообщение Mar 31 2014, 16:52
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Я делал так:
BX LR
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 1 2014, 03:01
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Omnicake @ Mar 31 2014, 16:56) *
LDR R0,[pc,#32]

Что у вас находится по адресу PC+32?
Совет: начинать нужно с изучения асма и архитектуры CPU, а не с выдёргивания чужих кусков наугад.
Go to the top of the page
 
+Quote Post
Omnicake
сообщение Apr 1 2014, 09:00
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002



По адресу pc+32 лежит записанное значение частоты процессора, а если быть точнее, преобразованная частота используемая для таймера. Я прекрасно понимаю, что я выдергиваю чужие команды, но чтобы начинать учится нужна какая-та практическая база. Любой reference manual для меня пока что - огромная куча регистров и функций, которые я пока не использую. Кстати после добавления BX LR все заработало, большое спасибо toweroff.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 1 2014, 12:11
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а что делает BX LR поняли?

дергать чужое - ок, но надо же читать что инструкции то делают. Если бы вы шли этим путем то узнали бы что ENDP, END это не инструкция проца, а кейловское слово для обозначения конца секции и файла...

Go to the top of the page
 
+Quote Post
toweroff
сообщение Apr 1 2014, 15:05
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(Golikov A. @ Apr 1 2014, 16:11) *
а что делает BX LR поняли?


первоисточник (тут):
Цитата
Register r14 is used as the subroutine Link Register (LR).

Register r14 receives the return address when a Branch with Link (BL or BLX) instruction is executed.

You can treat r14 as a general-purpose register at all other times. The corresponding banked registers r14_svc, r14_irq, r14_fiq, r14_abt, and r14_und are similarly used to hold the return values when interrupts and exceptions arise, or when BL or BLX instructions are executed within interrupt or exception routines.


Нужно просто разобраться, как компилятор формирует вызов функций вида "void func(void)"
Go to the top of the page
 
+Quote Post
Omnicake
сообщение Apr 6 2014, 23:07
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002



Цитата
Нужно просто разобраться, как компилятор формирует вызов функций вида "void func(void)"

У меня Keil сформировал файл main.s где прыгает по такой функции командой "B". Мне удалось включить таймер на ассемблере но возникла пара тонкостей, и чтобы новую тему не создавать спрошу тут:

1. Адресация через pc регистр действительно работала не так, как мне хотелось, поэтому адреса нужных мне регистров я стал загонять командой MOV, но встала проблема: адреса 32 битные, а команда MOV на Cortex-M3 ассемблере воспринимает только 16 битные переменные. Я использую команды MOVT и MOVW, по сути записывая адрес в два шага (в нижние 16 бит и в верхние), есть ли возможность как-то записывать адреса по-другому, или мне в дальнейшем так и использовать по две команды MOV.

2. Так и не смог понять правильного синтаксиса для обозначения меток в ассемблерном файле, так, чтобы отрабатывали команды BNE, CBZ и.т.д. Пробовал "Имя метки:" в начале строки, и потом "BNE Имя метки", пишет "Invalid line start". В созданных компилятором файлах, что-то похожее на метки обозначается как ||Имя метки||, но при попытках также сделать у себя, при компиляции Keil не распознает объект как метку. Где можно почитать про это поподробней?
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 23:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01441 секунд с 7
ELECTRONIX ©2004-2016