ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
23 ноября
14593
Bill (15.09.2004 21:04, просмотров: 840)
2 IgorKossak и др. Для дополнения темы. Поскольку я имею некоторый опыт http://www.caxapa.ru/mcu/wwwboard.html?id=14580
в реализации компилятора, рискну высказать несколько предположений. Для начала фрагмент кода сгенерированного моим компилятором для процессора 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 будут добавлены отдельные специальные подпрограммы для работы с константами в программной памяти. Еще раз подчеркиваю, что это только лишь мои предположения, не более.