Здесь видно, что для записи и извлечения чисел a и b используется 16-битные инструкции, а для сохранения результата их суммирования - уже 32-битная инструкция.
Причем здесь переполнение разрядности, если у Си вообще нет разрядности Он работает с типами и он способен производить неявные преобразования типов, даже если оба слагаемых равны 0. Если в языке определен тип бОльшей разрядности, то он и будет использован в результате. Вот тут видно:
В изначальном примере переменная результата суммирования имеет тип uint32_t, а значит, именно в нее будет записываться сумма и без обрезки на 16 битах. Если происходит обрезка, значит, компилятор какой-то "особенный". Вероятно, автор того пример имел ввиду другой случай - когда переменная слева представлена в меньшей разрядности, чем промежуточные результаты вычислений аргументов. То есть, когда выражение имеет несколько операторов, и промежуточный результат операций превышает разрядность переменной итогового результата. Да, тут может случиться обрезка, и возможно придется явно указывать тип промежуточных вычислений.
е - интересно бы послушать того, кто выдаёт новые сложные изделия хотя бы раз в месяц - ему точно без С++ никак - и где этот рынок, заваленный льющимся потоком новьём? r]
А послушайте новости по зомбоящику на Соловей-ТВ Будете поражены до глубины души, что страна развивается быстрее, чем Китай и "всё чисто российское" выдается "на гора", всё просто завалено "чисто российскими разработками"! И это просто чудо - ведь всего за два года из полного "ничего", из чисто потребительской страны она стала самой технологичной и быстроразвивающейся. Ура, товарищи, ура! (тут всем надо кидать шапки вверх и аплодировать несмолкаемо!)
Дядя. Ты суммируешь 16-битное целое без знака с другим таким же. А уже потом результат приводишь к 32-битному целому без знака. ВСЕ компиляторы работают по стандарту. Нет каких то "особенных".
Но я ведь показал результат на скринах выше - два числа используют инструкцию ldrh для 16-биного числа, но результат сохраняется инструкцией str для 32-битного числа. Ну и какие проблемы? Поведение компилятора задается его настройками. Там прописаны диапазоны чисел для типов, а используемые инструкции зависят от разрядности вычислительного ядра.
Ты суммируешь 16-битное целое без знака с другим таким же. А уже потом результат приводишь к 32-битному целому без знака. ВСЕ компиляторы работают по стандарту. Нет каких то "особенных".
Стандарт говорит компилятору все что не влазит в int сначала приводить к int:
Код:
uint16_t a = 40000, b = 30000; uint32_t ab = (int)a + (int)b;
На ПК и 16/32-х битных мк int 32-х битный и естественно получится 70000, а на 8-ми битках int может быть 16-ти битным, тогда uint16_t в int16_t не помещается и компилятор оставляет типы без изменений.
Обычно хватает ЯВУ и знаний, как тот или иной код должен работать и как он компилится в асм.
Ой, вот только не надо называть Си языком высокого уровня! Во-первых, он и создавался-то как язык среднего уровня, типа весьма продвинутого макроассемблера. А во-вторых, как только вы пишете что-то типа:
Код:
PORTB |= 0x03 компилится (-О1) в три команды - IN, ORI, OUT PORTB |= 0x01;PORTB |= 0x02; - в две команды SBI
так сразу же опускаетесь на низкий уровень, ибо не ЯВУшное это дело — ногами портов дрыгать. Программист должен понимать и постоянно помнить, что PORTB — это не переменная в ОЗУ, а какая-то периферия, и в ней может быть всё не так, как в ОЗУ, вплоть до того, что записал одно, а считал другое.
Цитата:
Я уже говорила - Язык Си - он мазохист. И получает цифровое удовольствие, когда программист стреляет себе в ногу. uint16_t a = 40000, b = 30000; uint32_t ab = a + b; чему равно ab ? Правильный ответ : 4464.
Ну так правильный же! Что в нём неправильного? Надо просто помнить, что это язык среднего уровня.
Беда в том что Асм он под конкретную архитектуру, его не перенесёшь куда то.
Just_Fluffy, вот здесь товарищ правильно пишет. И строчки типа PORTB|=0x01 — они тоже под конкретную архитектуру, их не перенесёшь куда-то, скажем, даже на соседнюю тиньку 24/44/84, у которой порта В почти нет (от него всего один бит, и он не только не нулевой , но даже и не первый), а есть только А. На самом деле этот вопрос чуть шире, чем градация между низким и высоким уровнем. Я как-то давненько говорил, что задачи бывают вычислительные и управленческие. Для вычислительных прекрасно подходят ЯВУ. А вот управленческие задачи на ЯВУ не решить без прибегания к низкому уровню, отсюда и костыли в Си для дрыгания ногами периферии. Отсюда же и радостные лозунги о предпочтительности ассемблера.
Стандарт говорит компилятору все что не влазит в int сначала приводить к int:
Нет в стандарте фразы "все что не влазит". Напротив, стандарт предписывает вести вычисления с равным приоритетом слева направо, то есть начинать с типа первого операнда, а он в примере Белой и Пушистой 16-разрядный. А у неё ещё и второй такой же. А приведение к типу результата будет выполняться только после завершения вычисления всей строки, когда результат уже будет усечён до 16 разрядов, то есть от него останется 4 тыщи с копейками. Поэтому переопределение типа (uint32_t) в этом примере достаточно дать только первому операнду. А вот расширения стандарта были всякие разные, их всех и не упомнишь.
Хех. Даже на Питоне можно ногами дрыгать, нет на это политического запрета. На языке Си дрыгание ногами организовано как запись числа по указанному адресу. Поэтому, разделять языки на уровни только по признаку доступа к ногам или иной периферии МК - не совсем верно. Вот например, ардуинщики (С++) используют digitalWrite - библиотечную функцию. Можно сказать, что С++ это язык высокого уровня, так? Хорошо, а если я напишу на этом же языке напрямую доступ к регистру портов - тогда это уже будет язык какого уровня - низкого?
Цитата:
костыли в Си для дрыгания ногами периферии
А что там не так? Например, в ARM-архитектуре вообще нет инструкций для прямого управления портами или иной периферией. Там вообще хоть на ассемблере, хоть на С/С++, хоть на Питоне - но сначала будет чтение из указанного адреса (ldr) во внутренние регистры ядра, затем модификация, и только затем запись (str) в указанный адрес.
Нет в стандарте фразы "все что не влазит". Напротив, стандарт предписывает вести вычисления с равным приоритетом слева направо, то есть начинать с типа первого операнда, а он в примере Белой и Пушистой 16-разрядный. А у неё ещё и второй такой же. А приведение к типу результата будет выполняться только после завершения вычисления всей строки, когда результат уже будет усечён до 16 разрядов, то есть от него останется 4 тыщи с копейками. Поэтому переопределение типа (uint32_t) в этом примере достаточно дать только первому операнду. А вот расширения стандарта были всякие разные, их всех и не упомнишь.
Нет, к int типы приводятся до выполнения операции сложения, иначе бы 250 + 10, если оба числа были типа uint8_t, дало в результате 4, а не 260. Если первый операнд привести к uint32_t, то второй тоже приведется к нему же, т.к. типы должны быть одинаковыми, а int, даже 32-х битный, уже uint32_t и к нему приводить нельзя. Так что не обязательно к uint32_t приводить именно первый операнд, достаточно чтобы такого типа был хотя бы один из них.
Например, в ARM-архитектуре вообще нет инструкций для прямого управления портами или иной периферией.
В новых кортексах кастомные инструкции есть, например, в Raspberry Pi Pico 2 к паре M33 прикрутили три вида таких инструкций, в том числе как раз для портов )
Давно я не держал в руках микроконтроллера со 128 байтами ОЗУ В последний раз это было лет... ну лет эдак 15 назад наверно ага, я помню ПИК16Ф84А у которого было вообще насколько на минималках всё, что акромя ассемблера ничего и не надо было. Но жизть то худо-бедно вперед идет, нынешние объемы ОЗУ в 1000 и более раз больше.
Напрасны у вас предубеждения, что на Си что-то не то получается. Навалять фигни на том же ассемблере куда проще, чем на Си. Я вот знавал одного господина, который хотел прогать STM32H743 непременно на ассемблере. Си он не хотел изучать по религиозным причинам. Ну и че, за пару лет мучений осилил лишь немного по таймерам и какой-то мелочи еще.
И между прочим, если "си-плюсами" правильно пользоваться, то оверхэда в потреблении оперативки не возникает. Ведь не обязательно же под любой чих создавать объект. А классы - это по большей части объединение в одну группу. То есть, когда не создаешь объект класса и когда все методы в классе - static, то лишняя оперативка и не потребляется.
Давно я не держал в руках микроконтроллера со 128 байтами ОЗУ В последний раз это было лет... ну лет эдак 15 назад наверно ага, я помню ПИК16Ф84А у которого было вообще насколько на минималках всё, что акромя ассемблера ничего и не надо было. Но жизть то худо-бедно вперед идет, нынешние объемы ОЗУ в 1000 и более раз больше.
Это предубеждение, что для мелких камней нужен только Асм. Не так давно писал человеку на Си для PIC10F200. Фигня конечно. Пару кнопок, светодиод, пассивный пьезо(!), сон(!). Просматривая листинг, подумал что на Асме было бы тоже самое.)
Код:
//Program space used 1AEh ( 430) of 200h words ( 84.0%) //Data space used 15h ( 21) of 18h bytes ( 87.5%)
Ну в древности я такое на ассемблере делал и покомпактнее. Вообще, в те далекие годы люди умудрялись упихивать в дохленькие ПИКи столько функционала. Когда ножек у МК было мало, мультиплексировали светодиоды с кнопками, интерфейс ЖКД WH1602 с клавиатурой, светодиоды во встречно-параллельном подключении. Сейчас я навряд ли буду страдать такими извратами. А некоторое время назад, до полупроводникового кризиса 2020-го, дешевле было взять STM32F030F4, чем PIC10F200. Цена СТМ-ки даже в дорогущем Чип-Дипе была 40 руб, а с алиэкспресса так и того дешевле.
Не надо меня агитироваь за См - я его нежно люблю и написа'л на нём много, пока не пересел на Дельфи. Но - на РС-шном. МК мне было как-то сподручней на асме. Впрочем, это - уже история
Иронию оценил. Увы, хоть я и выписал себе от Алика ST-шную тестовую платку и ST-Link, но заняться этим уже силов нет, и стимула. Добить бы как-то оставшиеся Тиньки, и то было бы хорошо.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения