Миландр

Ключевым подразделением нашей компании является Центр Проектирования интегральных микросхем
Текущее время: 2017-июл-26 05:44

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 7 ] 
Автор Сообщение
СообщениеДобавлено: 2014-янв-14 17:16 
Не в сети
Аватара пользователя

Зарегистрирован: 2013-июн-21 15:27
Сообщения: 66
Откуда: Новосибирск
В C-модуле для МК 1986ВЕ91Т пишу на встроенном ассемблере функцию, возвращающую текущий адрес точки вызова:

unsigned int GetCallerPC(void)
{
#pragma asm
SUB R0, LR, #4
AND R0, R0, #0xFFFFFFFE
#pragma endasm
}


Транслятор выдаёт ошибку "Error[C245] SampleC.c(39,0): (asm) Out of range" на инструкции AND. Что не так?
Вроде нормальная 32-разрядная константа для обнуления младшего разряда...
Заменил проблемную строку на "EOR R0, R0, #1" и теперь всё работает, но так и не понял, в чём тут ошибка.

_________________
Странник


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2014-янв-15 06:30 
Не в сети

Зарегистрирован: 2012-дек-11 21:35
Сообщения: 170
Откуда: Казань
stranderer писал(а):
В C-модуле для МК 1986ВЕ91Т пишу на встроенном ассемблере функцию, возвращающую текущий адрес точки вызова:

unsigned int GetCallerPC(void)
{
#pragma asm
SUB R0, LR, #4
AND R0, R0, #0xFFFFFFFE
#pragma endasm
}


Транслятор выдаёт ошибку "Error[C245] SampleC.c(39,0): (asm) Out of range" на инструкции AND. Что не так?
Вроде нормальная 32-разрядная константа для обнуления младшего разряда...
Заменил проблемную строку на "EOR R0, R0, #1" и теперь всё работает, но так и не понял, в чём тут ошибка.

Посмотрите в спецификации раздел "Формат второго операнда".
Открыть Константа
Данный тип второго операнда задается в формате:
#constant
где constant может быть:
• любой константой, которая может быть получена путем сдвига восьмиразрядного числа
влево на любое количество разрядов в пределах 32-разрядного слова;
• любая константа в виде 0x00XY00XY;
• любая константа в виде 0xXY00XY00;
• любая константа в виде 0xXYXYXYXY.
Во всех вышеописанных случаях X и Y представляют шестнадцатеричные цифры
Закрыть

Как я понял по описанию там любую константу указать нельзя. В вашем случаи можно использовать команду BIC.
Открыть BIC
Инструкция BIC выполняет операцию логического И между первым операндом,
содержащимся в регистре Rn, и инверсным значением второго операнда Operand2.
Закрыть

Попробуйте "BIC R0, R0, #1". EOR не прямая замена, для вашего случая может и пойдет.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2014-янв-15 20:26 
Не в сети
Аватара пользователя

Зарегистрирован: 2013-июн-21 15:27
Сообщения: 66
Откуда: Новосибирск
Спасибо!
Пожалуй, BIC действительно правильнее по смыслу, хотя в данном случае и то, и другое работает одинаково.
А что, константа вида 0xXYXYXYXY предполагает одинаковое значение каждого из 4 байт? Очень странное ограничение! Я-то как раз считал, что тут может быть ЛЮБОЕ 32-битное число...

_________________
Странник


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2014-янв-17 08:20 
Не в сети
Moderator

Зарегистрирован: 2010-мар-31 10:44
Сообщения: 54
Откуда: ООО "Фирма Фитон"
stranderer писал(а):
.... Я-то как раз считал, что тут может быть ЛЮБОЕ 32-битное число...

Здесь 32-битное число любым быть не может, т.к. Thumb-2 инструкции бывают только 16- и 32-битные. Непосредственный операнд может быть только частью этих 32 или 16 бит. В инструкциях типа AND непосредственное значение операнда кодируется 3-мя битовыми полями: i, imm3, imm8 - соответственно одно-, трех- и восьми-битные поля. Если в поле imm8 записано двоичное значение abcdefgh, то всевозможные варианты формирования 32-битной констаны указаны в таблице:
Код:
i imm3 a     <const32>
0 000  x     00000000 00000000 00000000 abcdefgh
0 001  x     00000000 abcdefgh 00000000 abcdefgh (!)
0 010  x     abcdefgh 00000000 abcdefgh 00000000 (!)
0 011  x     abcdefgh abcdefgh abcdefgh abcdefgh (!)

8-bit values shifted to other positions
0 100  0     1bcdefgh 00000000 00000000 00000000
0 100  1     01bcdefg h0000000 00000000 00000000
0 101  0     001bcdef gh000000 00000000 00000000
0 101  1     0001bcde fgh00000 00000000 00000000
.................
1 110  1     00000000 00000000 000001bc defgh000
1 111  0     00000000 00000000 0000001b cdefgh00
1 111  1     00000000 00000000 00000001 bcdefgh0

(!) UNPREDICTABLE if abcdefgh == 00000000.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2014-янв-17 21:35 
Не в сети
Аватара пользователя

Зарегистрирован: 2013-июн-21 15:27
Сообщения: 66
Откуда: Новосибирск
Спасибо! Я понял.

Ещё пара вопросов о константах:
1. Можно ли в С-модуле как-то использовать .PUBLIC-константы, заданные, например, как
Size .EQU EndAddr - StartAddr
и если да, то какой у них д.б. тип?
2. Можно ли в С-модуле описать константы с заданными конкретными адресами в EEPROM? Я пробовал #pragma locate но транслятор выдаёт ошибку. А мне нужно поместить массив констант с начала страницы EEPROM, чтобы обеспечить возможность перезаписи этой конкретной страницы в процессе работы изделия. Пока пришлось создавать ассемблерный модуль исключительно для описания таких констант, но это по некоторым причинам не совсем удобно, хоть и работает...

_________________
Странник


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2014-янв-20 12:07 
Не в сети
Moderator

Зарегистрирован: 2010-мар-31 10:44
Сообщения: 54
Откуда: ООО "Фирма Фитон"
stranderer писал(а):
1. Можно ли в С-модуле как-то использовать .PUBLIC-константы, заданные, например, как
Size .EQU EndAddr - StartAddr
и если да, то какой у них д.б. тип?
Нельзя. Константные значения в различные модули программы на C передаются посредством включения общих заголовочных файлов. Формат .inc-файла ассемблера не соответствует формату заголовочного файла C.

stranderer писал(а):
2. Можно ли в С-модуле описать константы с заданными конкретными адресами в EEPROM? Я пробовал #pragma locate но транслятор выдаёт ошибку. А мне нужно поместить массив констант с начала страницы EEPROM, чтобы обеспечить возможность перезаписи этой конкретной страницы в процессе работы изделия. Пока пришлось создавать ассемблерный модуль исключительно для описания таких констант, но это по некоторым причинам не совсем удобно, хоть и работает...
Приведите Ваш пример использования #pragma locate, где компилятор выдает ошибку.
Я опробовал вот такой фрагмент:
Код:
#pragma locate MyConst 0x08004000
unsigned int const MyConst[] = {0,1,2,3};

void main(void)
{
  while(1)
  {
    if (MyConst[0] == 1) return;
  }
}
- компилируется без ошибок.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2014-янв-20 22:03 
Не в сети
Аватара пользователя

Зарегистрирован: 2013-июн-21 15:27
Сообщения: 66
Откуда: Новосибирск
Я пробовал примерно то же самое в CodeMaster-ARM v2.28 (а то и раньше) и получал сообщение об ошибке "Bad pragma locate", поэтому переписал модуль на ассемблере и с тех пор к этому вопросу не возвращался. Теперь действительно работает! Видимо в текущей версии компилятора это баг уже исправлен.
Спасибо, теперь буду пользоваться!

_________________
Странник


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 7 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB