2 IgorKossak и др. Для дополнения темы. Поскольку я имею некоторый опыт http://www.caxapa.ru/mcu/wwwboard.html?id=14580
в реализации компилятора, рискну высказать несколько предположений. Для начала фрагмент кода сгенерированного моим компилятором для процессора Z80 (комментарии (;;; ) добавлены мною для ясности)
в реализации компилятора, рискну высказать несколько предположений. Для начала фрагмент кода сгенерированного моим компилятором для процессора Z80 (комментарии (;;; ) добавлены мною для ясности)
.psect $$DATA ;;; Секция для размещения данных _lng: ;static long lng; .blkb 4 _flt: ;static float flt; .blkb 4 ........................ ; if (lng < 123L) ; lng = 123; ; .psect $$INIT ;;; Секция для размещения констант $3: .word 173, 0 ;;; Константа 123L .psect ld hl,_lng ;;; Загрузить lng в long аккумулятор call CGET$L ;;; ld hl,$3 ;;; Установить указатель на константу call C$LT$L ;;; Выполнить сравнение jp p,$2 ;;; Переход если >= ld hl, 173 ;;; Преобразовать 123 в тип long call CCVI$L ;;; результат в long аккумуляторе ld hl,_lng ;;; загрузить в переменную lng call CPUT$L ;;; $2: ............................. Аналогично для типа float ; if (flt > 0.5) ; flt = 0.5; ; .psect $$INIT $5: .flt2 0.5 ;;; Константа 0.5 .psect ld hl,_flt ;;; Загрузить flt в float вккумулятор call CGET$F ;;; ld hl,$5 ;;; Установить указатель на константу call C$GT$F ;;; Выполнить сравнение jp p,$4 ;;; Переход если <= .psect $$INIT $6: .flt2 0.5 .psect ld hl,$6 ;;; Загрузить константу 0.5 в float аккумулятор call CGET$F ;;; ld hl,_flt ;;; Запомнить содержимое float аккумулятора call CPUT$F ;;; в переменной flt $4: ...................Процессор Z80 имеет небольшое число регистров и ЕДИНОЕ адресное пространство. Для выполнения операций над типами long и float регистров процессора недостаточно, поэтому один из операндов должен размещаться в памяти. Для хранения этих операндов в ОЗУ выделялись специальные ячейки под аккумуляторы данных типов (long и float). Все константы этих типов размещались в программной секции $$INIT. Для выполнения операций с данными этих типов (в том числе операций сравнения) генерировался вызов служебных подпрограмм. Процессор AVR имеет достаточное число регистров для размещения обоих 32-разрядных операндов, поэтому константы сразу же размещаются в регистрах побайтно, им не нужно выделять оперативную память. В случае использования типов long long и double, регистров процессора уже недостаточно для их размещения, и для них требуется дополнительная память, примерно так, как сделал в свое время я сам для Z80. Это первое предположение. Далее, поскольку адресные простанства программ (ПЗУ) и данных(ОЗУ) разделены, то механизмы доступа к константам и данных должны быть различны. Кроме того, поскольку для выполения операций над данными должны вызываться соответствующие подпрограммы (это второе предположение), то они сделаны в предположении, что операнды расположены в ОЗУ (как наиболее общий случай). Компилятор не различает мест размещения данных. Поэтому вполне естественно, что все константы указанных типов должны при инициализации программы в startup должны пересылаться в SRAM. Третье (и последнее) предположение. Поскольку тип long long стал доступным только в последних версиях компилятора, то можно надеяться, что в последующих версиях для работы с данными типа long long будут добавлены отдельные специальные подпрограммы для работы с константами в программной памяти. Еще раз подчеркиваю, что это только лишь мои предположения, не более.
-
- Все остальное здесь Bill(1879 знак., 15.09.2004 21:06)
- Весьма точные предположения. Спасибо! - IgorKossak(16.09.2004 12:18)
- Все остальное здесь Bill(1879 знак., 15.09.2004 21:06)