Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с условием
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
ave!
Добрый день!

Я переношу чужую программу с AVR на STM32 (под HAL Keil).

m = m+I|P == I ? m : 0;

Эта строка выдает предупреждение: "| имеет более низкий приоритет, чем ==; == будет оцениваться сначала"
Когда пишу m = (m+I|P) == I ? m : 0; предупреждение исчезает, но я не знаю можно ли так писать, не нарушит ли эта запись условие.

Таких предупреждений много и есть более сложные выражения.

if (x+r-y|u&32|p > 2&(p-4|j-7 || b[G=x+3^r>>1&7]-k-6 || b[G^1]|b[G^2])) t += p<5; else F = y;

Warning: '&' within (внутри) '|'
Warning: & has lower precedence than >; > will be evaluated first
Warning: '&' within (внутри) '|'

Подскажите ссылку где можно поучится этим условиям в контексте моей проблемы.
aaarrr
Цитата(ave! @ Aug 20 2018, 11:18) *
Подскажите ссылку где можно поучится этим условиям в контексте моей проблемы.

Гуглите "c operator precedence".

Надо заметить, что это -
Код
if (x+r-y|u&32|p > 2&(p-4|j-7 || b[G=x+3^r>>1&7]-k-6 || b[G^1]|b[G^2])) t += p<5; else F = y;

- просто прекрасно. В жизни не видел такой красоты в реальных проектах.
segment
Воу. Если не секрет, то что это за проект такой? А так, Вам необходимо просто почитать о приоритетах операторов.
ViKo
Дык, обфускация.
segment
Да, да, она или дизассемблировано. Просто я однажды видел нечто подобное, написанное руками — математик пытался закодировать свои формулы, и у него получилось где-то с десяток тысяч строк подобного кода.
Сергей Борщ
QUOTE (ave! @ Aug 20 2018, 11:18) *
m = m+I|P == I ? m : 0;

Эта строка выдает предупреждение: "| имеет более низкий приоритет, чем ==; == будет оцениваться сначала"
Когда пишу m = (m+I|P) == I ? m : 0; предупреждение исчезает, но я не знаю можно ли так писать, не нарушит ли эта запись условие.
Скобки вы расставили неправильно даже несмотря на подсказку компилятора. Если автор исходного кода знал приоритеты операций (а судя по всему он их знал), то скобки должны стоять так: m = ((m + I) | (P == I)) ? m : 0.

P.S. В последнее время компиляторы что-то уж больно часто стали ругаться на очевидные выражения. Неужели настолько упал уровень основной массы современных программистов, что они не в состоянии запомнить приоритет операторов? Жду - не дождусь, когда компилятор начнет требовать скобки в выражении a*x+b.
aaarrr
Цитата(ViKo @ Aug 20 2018, 11:57) *
Дык, обфускация.

Для обычной обфускации это как-то слишком. Тут что-то болезненное просматривается.

Цитата(Сергей Борщ @ Aug 20 2018, 12:01) *
P.S. В последнее время компиляторы что-то уж больно часто стали ругаться на очевидные выражения...

GCC еще и замены предлагает в гугл-стиле: "а не имели ли Вы, уважаемый, в виду A, а не B?"
А ведь кто-то просто последует такой рекомендации не вникая.
Непомнящий Евгений
Цитата(Сергей Борщ @ Aug 20 2018, 12:01) *
Скобки вы расставили неправильно даже несмотря на подсказку компилятора. Если автор исходного кода знал приоритеты операций (а судя по всему он их знал), то скобки должны стоять так: m = ((m + I) | (P == I)) ? m : 0.

P.S. В последнее время компиляторы что-то уж больно часто стали ругаться на очевидные выражения. Неужели настолько упал уровень основной массы современных программистов, что они не в состоянии запомнить приоритет операторов? Жду - не дождусь, когда компилятор начнет требовать скобки в выражении a*x+b.


Вот ни разу не очевидное выражение maniac.gif Плюс что-то кажется мне, что тут правильней не бинарное или, а логическое.

А по теме - врядли в IAR и gcc разный приоритет операторов, если проект у вас был рабочий - оставьте как есть, просто отключите эти ворнинги. Если хотите улучшить читаемость - лучше ее отдельно улучшать, после того как перенесенный проект заработает в таком виде
ave!
Цитата(segment @ Aug 20 2018, 11:55) *
Воу. Если не секрет, то что это за проект такой?

Это не секрет, это шахматная программа micro-Max.
Весь код помещается на одном листе А4, притом, что программа знает даже такое правило, как "взятие пешки на проходе".
Мне этот алгоритм очень понравился, я когда-то с друзьями в турнир играл, четырех обыграл, а эта програмка меня взувает (сделал шахматный калькулятор на ATmega48).
Тут верно заметили, что код писал математик.
Спасибо за советы.
jcxz
Цитата(ave! @ Aug 20 2018, 11:18) *
if (x+r-y|u&32|p > 2&(p-4|j-7 || b[G=x+3^r>>1&7]-k-6 || b[G^1]|b[G^2])) t += p<5; else F = y;

Типичный говнокод, а не обфускация. Ибо приводить тип bool к численному - дурная манера, которая может вылезти боком при переходе на другой компилятор. И нормальный обфускатор такое делать не станет.
Да и просто это ведёт к неоптимальному коду.
Сергей Борщ
QUOTE (Непомнящий Евгений @ Aug 20 2018, 13:18) *
Вот ни разу не очевидное выражение
Приоритет операций известен. Да, оно сложнее, чем a+b, но ничего неоднозначного и тем более неочевидного в нем нет. В a*x+b тоже будем скобки расставлять?

QUOTE (Непомнящий Евгений @ Aug 20 2018, 13:18) *
Плюс что-то кажется мне, что тут правильней не бинарное или, а логическое.
С этим согласен.
jcxz
Цитата(ave! @ Aug 20 2018, 13:29) *
Тут верно заметили, что код писал математик.

Код писал извращенец человек, цель которого была совсем не оптимальность и не решение практической задачи, а цель - вычурность кода.
Ибо: вместо t += p<5 простой программист использует if, а более продвинутый заменит на что-то типа: t -= (int)(p - 5) >> 31;
ave!
Цитата(Сергей Борщ @ Aug 20 2018, 12:01) *
Скобки вы расставили неправильно даже несмотря на подсказку компилятора. Если автор исходного кода знал приоритеты операций (а судя по всему он их знал), то скобки должны стоять так: m = ((m + I) | (P == I)) ? m : 0.


Сергей Борщ, я скопировал все 7 предупреждений.
Может у вас будет настроение расставить все скобки.
Буду вам очень благодарен.
Чувствую, что даже после изучения приоритетов я все-равно где-то, что-то не так сделаю.
Программа скомпилируется и даже работать будет, но это шахматный алгоритм, там можно не понять что что-то не так работает.

(1) while (d++<n||d<3||z&K==I&&(N<T&d<98||(K=X,L=Y&~M,d=3)))

(2) while (r=p>2&r<0?-r:-o[++j])

(3) if (t&k|p<3&!(y-x&7)-!t)

(4) v-=p-4|R>29?0:20;

(5) Y=y|S&F;

(6) if (x+r-y|u&32|p>2&(p-4|j-7||b[G=x+3^r>>1&7]-k-6||b[G^1]|b[G^2]))

(7) m=m+I|P==I?m:0;
Исправление готово: m = ((m+I)|(P==I)) ? m : 0;

Мой случай как раз яркий пример для статьи на хабре:
Как вы пишете условия в СИ-подобных языках? Со скобками в условиях или без?
jcxz
Цитата(ave! @ Aug 20 2018, 14:36) *
Исправление готово: m = ((m+I)|(P==I)) ? m : 0;

Эта конструкция скомпилится в большее число команд, чем простое, читаемое и аналогичное по результату: if (!(m + I) && P != I) m = 0;
И в других местах - аналогично.
Поэтому единственная цель такого поделия - сделать вычурный код.
_pv
Цитата(jcxz @ Aug 20 2018, 18:47) *
Поэтому единственная цель такого поделия - сделать вычурный код.

ну собственно так там и написано
Цитата
My original aim was to write a chess program smaller than 1024 characters

ave!
Приоритет операций C++ - это я себе в тему на заметку.

Цитата(jcxz @ Aug 20 2018, 14:47) *
Эта конструкция скомпилится в большее число команд, чем простое, читаемое и аналогичное по результату: if (!(m + I) && P != I) m = 0;
И в других местах - аналогично.
Поэтому единственная цель такого поделия - сделать вычурный код.

jcxz, может вы поможете разобраться с остальными местами по списку.
jcxz
Цитата(ave! @ Aug 20 2018, 15:20) *
jcxz, может вы поможете разобраться с остальными местами по списку.

Мне кажется первая строчка к си не относится. Или там ошибка. Вы там где-то имя функции не забыли? Иначе компилятор должен был ругнуться.
В чём там разбираться? Компилируется? Работает? Тогда зачем разбираться?
А если не работает - отлаживать? нет уж, увольте rolleyes.gif
Непомнящий Евгений
Цитата(Сергей Борщ @ Aug 20 2018, 14:25) *
Приоритет операций известен. Да, оно сложнее, чем a+b, но ничего неоднозначного и тем более неочевидного в нем нет. В a*x+b тоже будем скобки расставлять?


это конечно вкусовщина, но я бы расставил для всего кроме арифметических операторов. Наверное у меня такого кода очень мало и мне лень учить приоритеты, а также задумываться - разные ли они в си, питоне, яваскрипте и т.п.
ave!
Цитата(jcxz @ Aug 20 2018, 15:23) *
Мне кажется первая строчка к си не относится. Или там ошибка. Вы там где-то имя функции не забыли? Иначе компилятор должен был ругнуться.

Код рабочий, на AVR компилируется без ошибок и предупреждений. Предупреждения только при переносе на STM.
На самом деле это с моей стороны извращение пытаться понять этот код.

Стиль написания самой функции поиска следующего хода для меня не понятна:

short D(q,l,e,E,z,n)
short q,l,e;
unsigned char E,z,n;
{
//...
}

Я подозреваю, что это тоже самое что:

short D(short q, short l, short e, unsigned char E, unsigned char z, unsigned char n) {
//...
}

Под AVR компилятор пропустил и первую запись, а вот под STM не прошло.
jcxz
Цитата(ave! @ Aug 20 2018, 16:05) *
Стиль написания самой функции поиска следующего хода для меня не понятна:
short D(q,l,e,E,z,n)

Возможно там макросами что-то переопределено.

Цитата(ave! @ Aug 20 2018, 14:36) *
(1) while (d++<n||d<3||z&K==I&&(N<T&d<98||(K=X,L=Y&~M,d=3)))

Но такое не должно компилиться. имхо. выделенное.
Сергей Борщ
QUOTE (jcxz @ Aug 20 2018, 16:24) *
Возможно там макросами что-то переопределено.
Это K&R style, поддерживается компиляторами для совместимости с самыми старыми исходниками (созданными еще до принятия Стандарта языка), сейчас практически не применяется и это правильно.
QUOTE (jcxz @ Aug 20 2018, 16:24) *
Но такое не должно компилиться. имхо. выделенное.
Почему? Оператор "запятая" никто не отменял.


QUOTE (ave! @ Aug 20 2018, 16:05) *
Я подозреваю, что это тоже самое что:
Да, именно так.
jcxz
Цитата(Сергей Борщ @ Aug 20 2018, 16:28) *
Это K&R style, сейчас практически не применяется и это правильно.

и ну его... в сад. rolleyes.gif
yes
ну дык (по описанию micro-Max) задача стояла минимум символов в коде, поэтому такой код
была такая специальная олимпиада по С программированию sm.gif, помню печать кода программы в стдаут, например, но чтобы шахматы - это охренеть
jcxz
Цитата(yes @ Aug 20 2018, 17:28) *
ну дык (по описанию micro-Max) задача стояла минимум символов в коде, поэтому такой код
была такая специальная олимпиада по С программированию sm.gif, помню печать кода программы в стдаут, например, но чтобы шахматы - это охренеть

А я вот помню что когда-то умудрялись написать программу в ASCII-символах. Т.е. - файл программы состоял только из байтов печатаемого диапазона ASCII-кодов: 33...126.
Отсылаешь такую прогу как обычный текст, сохраняешь в файл, переименовываешь его в расширение .com и запускаешь rolleyes.gif
Без всякого base- или uue-кодирования. А если применительно к МК, то никакого .hex тогда не надо, .bin вполне текстовый был бы.
Arlleex
Цитата(jcxz @ Aug 20 2018, 15:31) *
Ибо: вместо t += p<5 простой программист использует if, а более продвинутый заменит на что-то типа: t -= (int)(p - 5) >> 31;


А еще результат выражения != 0 не обязательно есть 1. Поэтому тот, кто писал t += p<5, явно чудак biggrin.gif
jcxz
Цитата(Arlleex @ Aug 22 2018, 15:33) *
А еще результат выражения != 0 не обязательно есть 1. Поэтому тот, кто писал t += p<5, явно чудак biggrin.gif

Я об этом писал ещё в 10-м посте:
Цитата(jcxz @ Aug 20 2018, 14:17) *
Ибо приводить тип bool к численному - дурная манера, которая может вылезти боком при переходе на другой компилятор.
Сергей Борщ
QUOTE (Arlleex @ Aug 22 2018, 15:33) *
А еще результат выражения != 0 не обязательно есть 1.
Обязательно есть.
QUOTE (Arlleex @ Aug 22 2018, 15:33) *
Поэтому тот, кто писал t += p<5, явно чудак biggrin.gif
Тот, кто писал этот код, очень хорошо знал Стандарт языка. В отличие от вас.
QUOTE
6.5.8 Relational operators
6 Each of the operators < (less than), > (greater than), <= (less than or equal to), and >=
(greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.89)
The result has type int.
6.5.9 Equality operators
The == (equal to) and != (not equal to) operators are analogous to the relational
operators except for their lower precedence.90) Each of the operators yields 1 if the
specified relation is true and 0 if it is false. The result has type int.
Arlleex
Цитата(Сергей Борщ @ Aug 22 2018, 16:55) *
Обязательно есть.
Тот, кто писал этот код, очень хорошо знал Стандарт языка. В отличие от вас.

Вон оно как? Стандартов не читал, да, признаю.
Но вот будет ли так в дальнейшем - не совсем ясно, поэтому так писать лично я бы не стал. Ведь компиляторы все новее и новее, а оптимизация все хитрее. Никто не знает, во что это выльется в будущем.
jcxz
Цитата(Arlleex @ Aug 25 2018, 10:08) *
Но вот будет ли так в дальнейшем - не совсем ясно, поэтому так писать лично я бы не стал. Ведь компиляторы все новее и новее, а оптимизация все хитрее. Никто не знает, во что это выльется в будущем.

Я тоже выше об этом писал. Понятно что сейчас это работает. Но такой подход и стиль считаю плохим.
char тоже раньше всегда был знаковым, а сейчас может быть и беззнаковым, в зависимости от установок компилятора. Всё потому, что в появились некоторые CPU, в которых чтение/запись беззнаковых char короче чем знаковых, и во многих случаях, когда знаковость не важна, лучше использовать такие операции чтения/записи.
Так и с этим - если CPU позволяет более эффективно работать с типами bool со значениями 0/-1, а не 0/1, то лучше так и делать, разрешив спец.опцией компилятора. Хотя конечно это гораздо менее часто встречающаяся потребность чем char, значит не очень важная.
Arlleex
Цитата(jcxz @ Aug 25 2018, 10:21) *
Я тоже выше об этом писал. Понятно что сейчас это работает. Но такой подход и стиль считаю плохим.
char тоже раньше всегда был знаковым, а сейчас может быть и беззнаковым, в зависимости от установок компилятора.

Про CPU с различными подходами в копировании char не знал, спасибо. Интересно конечно, как это может так быть - ведь копируются 8 бит все равно...

А вот размышления вслух, можно сказать.
Допустим есть условие if(x != y) или просто выражение z = (x != y). Переменные целые. Я бы на месте компилятора сделал что-то наподобие z = x - y или z = x ^ y. И если z равно 0, то это значило, что x == y. А если не равно 0, то, соответственно, x != y. Вот типичный случай, когда не нужны были бы лишние телодвижения по установке значения 1 в переменную вместо прямого присваивания результата вычитания. Меньше инструкций ведь по факту. И таких примеров оптимизаций, ИМХО, можно как-то еще придумать. Опять же, просто исходя из логики рассуждаю laughing.gif
ViKo
Поскольку было объяснение, что писалось на конкурс уложить код в 1К, то допустимы и приветствуются любые извращения. Классические принципы здесь не нужны.
jcxz
Цитата(Arlleex @ Aug 25 2018, 10:39) *
Про CPU с различными подходами в копировании char не знал, спасибо. Интересно конечно, как это может так быть - ведь копируются 8 бит все равно...

Загляните как-нить в листинг Cortex-M3/4 кода и сравните команды LDRB и LDRSB например. Поймёте почему.
Для этого имхо и ввели дополнительный чекбокс в IAR "signed/unsigned char".
Arlleex
Цитата(jcxz @ Aug 25 2018, 10:59) *
Загляните как-нить в листинг Cortex-M3/4 кода и сравните команды LDRB и LDRSB например. Поймёте почему.
Для этого имхо и ввели дополнительный чекбокс в IAR "signed/unsigned char".

Сходу не получилось заставить компилятор сгенерировать LDRSB...
Использую armcc в составе Keil. Оптимизация 0. Галка "Plain Char is Signed" сброшена.
Код
Код
volatile signed char a = 10;
volatile signed char b = 20;
volatile signed char c;

int main(void)
{
    c = a - b;
    
    while(1);
}

формирует следующий листинг
Код
0x080002E0 4805      LDR           r0,[pc,#20]
0x080002E2 7800      LDRB          r0,[r0,#0x00]; загрузили a
0x080002E4 4905      LDR           r1,[pc,#20]
0x080002E6 7809      LDRB          r1,[r1,#0x00]; загрузили b
0x080002E8 1A40      SUBS          r0,r0,r1     ; вычли
0x080002EA B240      SXTB          r0,r0        ; ИМХО, лишнее, т.к. SUBS работает 32-битными числами
0x080002EC 4904      LDR           r1,[pc,#16]
0x080002EE 7008      STRB          r0,[r1,#0x00]; загружаем результат в переменную c

В случае, если переменные объявить без спецификатора signed (то есть с unsigned) то листинг тот же самый, но без SXTB

С оптимизацией -O3 для signed/unsigned листинг одинаковый:
Код
0x0800028C 4803      LDR           r0,[pc,#12]
0x0800028E 7801      LDRB          r1,[r0,#0x00]
0x08000290 7842      LDRB          r2,[r0,#0x01]
0x08000292 1A89      SUBS          r1,r1,r2
0x08000294 7081      STRB          r1,[r0,#0x02]
jcxz
Цитата(Arlleex @ Aug 25 2018, 12:23) *
Сходу не получилось заставить компилятор сгенерировать LDRSB...
Использую armcc в составе Keil. Оптимизация 0. Галка "Plain Char is Signed" сброшена.

Всего лишь оптимизация умного компилятора rolleyes.gif
Вы сами подумайте: раз Вы результат обратно сокращаете до 8 бит, то зачем тогда старшие биты вычислять? А если их вычислять не нужно, то можно ограничиться командами LDRB как более "дешёвыми". laughing.gif
Тест Ваш построен некорректно. Для корректности теста сделайте int volatile c. Тогда, думаю, увидите LDRSB.
Ну и для теста можно одно из a или b сделать отрицательным.

Цитата(Arlleex @ Aug 25 2018, 12:23) *
0x080002EA B240 SXTB r0,r0 ; ИМХО, лишнее, т.к. SUBS работает 32-битными числами

Хоть это и лишнее, но это был намёк компилятора, что он заметил достаточность использования 8-бит для результата и поэтому не стал заморачиваться с правильным расширением входных аргументов. rolleyes.gif

PS: Код теста не совсем корректный, так как должен вызвать warning "undefined behavior".
Arlleex
Цитата(jcxz @ Aug 25 2018, 12:59) *
Тест Ваш построен некорректно. Для корректности теста сделайте int volatile c. Тогда, думаю, увидите LDRSB.

Точно! И вправду LDRB заменились на LDRSB... Просто с расширением знака. Все четко по описанию команды загрузки с расширением знака rolleyes.gif
Единственное, что отмечу. Разницы в количестве тактов выполнения не заметно... То есть по факту выполняются они одинаково по времени, только лишь представление числа в памяти нужным образом расширяется или нет, вот и вся разница, вроде как.

Цитата(jcxz @ Aug 25 2018, 12:59) *
PS: Код теста не совсем корректный, так как должен вызвать warning "undefined behavior".

Из-за int перед main() и отсутствия возвращаемого результата? Тогда не неопределенное поведение, а что-то типа "недостижимый участок кода" и "отсутствие возвращаемого значения в функции, которая возвращает int"... Но Keil не паникует, кстати... laughing.gif
jcxz
Цитата(Arlleex @ Aug 25 2018, 13:24) *
Единственное, что отмечу. Разницы в количестве тактов выполнения не заметно... То есть по факту выполняются они одинаково по времени, только лишь представление числа в памяти нужным образом расширяется или нет, вот и вся разница, вроде как.

Конечно разницы в тактах нет при условии наличия команды в кеше/конвеере CPU. Но в реальном МК команду ещё нужно выбрать из памяти, а ширина шины к памяти программ не бесконечна, как и скорость последней.
Так что по времени выполнения - Вы не правы.

Цитата(Arlleex @ Aug 25 2018, 13:24) *
Из-за int перед main() и отсутствия возвращаемого результата?

Нет. Из-за того, что в одном выражении используются две volatile-переменные. Порядок чтения которых внутри выражения неопределён. А volatile подразумевает строгость в порядке доступа.

Цитата(Arlleex @ Aug 25 2018, 13:24) *
Но Keil не паникует, кстати... laughing.gif

А зря. IAR реагирует на подобные выражения: "undefined behavior".
Arlleex
Цитата(jcxz @ Aug 25 2018, 15:24) *
Конечно разницы в тактах нет при условии наличия команды в кеше/конвеере CPU. Но в реальном МК команду ещё нужно выбрать из памяти, а ширина шины к памяти программ не бесконечна, как и скорость последней.
Так что по времени выполнения - Вы не правы.

Открыл TRM на Cortex-M3. Вижу, что CPI на LDRB и на LDRSB одинаковы и составляют 2 такта. Одинакова и их синтаксическая запись. Существуют как 16-битные, так и 32-битные версии обеих команд. При всех прочих равных условиях время выполнения LDRB и LDRSB одинаково.
То, что команду нужно выбрать из памяти - это понятно. Но LDRB нужно выбрать точно так же, как и LDRSB в одном и том же коде. Ничем не отличается.
Другое дело, если мы говорим о том, что загружать значение как оно есть и лишь потом программно еще расширять знак. Там да, несколько команд нужно: тот же LDRB + расширение знака, если требуется.

Цитата(jcxz @ Aug 25 2018, 15:24) *
Нет. Из-за того, что в одном выражении используются две volatile-переменные. Порядок чтения которых внутри выражения неопределён. А volatile подразумевает строгость в порядке доступа.

Да, в упор не увидел очевидное... Жаль Keil не ругнулся никак даже при установке "All Warnings" в настройках компилятора crying.gif
jcxz
Цитата(Arlleex @ Aug 25 2018, 16:23) *
Открыл TRM на Cortex-M3. Вижу, что CPI на LDRB и на LDRSB одинаковы и составляют 2 такта. Одинакова и их синтаксическая запись. Существуют как 16-битные, так и 32-битные версии обеих команд. При всех прочих равных условиях время выполнения LDRB и LDRSB одинаково.

А Вы когда-нибудь пробовали заглядывать в листинг? И сколько вы там видели LDRB разной длины и сколько LDRSB? laughing.gif
Формы-то может и есть, тут вопрос в количестве....
Попробуйте в .asm-файле ввести 2 такие команды и скомпилить:
Код
LDRB     R0, [R0, #0]
LDRSB     R0, [R0, #0]
А потом попробуйте поизменять регистры от R0 до R7 и посмотреть что получается.
А теперь загляните в листинги и увидите, что большинство обращений к памяти как раз подобные формы команд: косвенная с константным смещением.
Arlleex
Цитата(jcxz @ Aug 25 2018, 16:49) *
А Вы когда-нибудь пробовали заглядывать в листинг? И сколько вы там видели LDRB разной длины и сколько LDRSB? laughing.gif
Формы-то может и есть, тут вопрос в количестве....

Мда, в листинге действительно LDRSB используются всегда 32-битные, очевиден проигрыш... Причем какие бы регистры не использовали - младшие или старшие - все равно берется команда Thumb-2 (32 бит). А вот LDRB, при использовании младших регистров в качестве операндов, компилируется в 16-битной Thumb форме; при использовании старших регистров - законно Thumb-2.

P.S. Почитал тут в мануале.
Если запись команды LDRSB использует форму с непосредственным смещением от базового регистра, то такая команда существует только 32-битная. Для LDRB такая команда есть в 16 битах, только там непосредственное значение ограничено 5 битами. Теперь все понятно!

jcxz, благодарю за полезную информацию rolleyes.gif
Obam
Во времена настали: раздел про AVR, а тут про приготовление ARMов.
jcxz
Цитата(Obam @ Aug 25 2018, 22:46) *
Во времена настали: раздел про AVR, а тут про приготовление ARMов.

А что - AVR ещё жив? rolleyes.gif
Obam
Ну, на фоне 6502 и z80 вполне себе...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.