Страница 1 из 1

Непонятный код subi r17,high(1)

Добавлено: Пн дек 25, 2017 22:36:20
ultexplorer
Здравствуйте!
Помогите разобраться в коде.
Что это означает:

Код: Выделить всё

subi 	Tmp1,Low(1)
А потом следует

Код: Выделить всё

sbci 	Tmp1,High(1) 
Как у единицы может быть старшая и младшая тетрады?
Ведь low(metka) или high(metka) означает обращение к младшему и старшему байту метки metka.
А low(1) или high(1) мои мо́зги обнуляют...
Объясните пожалуйста!

Код взят из статьи об операционной системе для avr. Вот источник http://easyelectronics.ru/avr-uchebnyj- ... ment-41895

Вот весь макрос с этим кодом:

Код: Выделить всё

.MACRO TimerService
					push 	Tmp1
			in 		Tmp1,SREG			; Save Sreg
			push 	Tmp1				; Сохранение регистра Tmp1 и регистра состояния SREG

			push 	ZL	
			push 	ZH					; сохранение Регистра Z
			push 	Counter				; сохранение Регистра Counter
	
			ldi 	ZL,low(TimersPool)	; Загрузка с регистр Z адреса RAM, 
			ldi 	ZH,high(TimersPool); по которому находится информация о таймерах

			ldi 	Counter,TimersPoolSize ; максимальное количество таймеров
	
Comp1L01:	ld 		Tmp1,Z				; Tmp1 = [Z] ; Получить номер события
			cpi 	Tmp1,$FF			; Проверить на "NOP"
			breq 	Comp1L03			; Если NOP то переход к следующей позиции

			clt							; Флаг T используется для сохранения информации об окончании счёта
			ldd 	Tmp1,Z+1			; 
			subi 	Tmp1,Low(1) 		; Уменьшение младшей части счётчика на 1
			std 	Z+1,Tmp1			;
			breq 	Comp1L02			; Если 0 то флаг T не устанавливаем
			set							; 

Comp1L02:	ldd 	Tmp1,Z+2			;
			sbci 	Tmp1,High(1) 		; Уменьшение старшей части счётчика на 1
			std 	Z+2,Tmp1			;
			brne 	Comp1L03			; Счёт не окончен
			brts 	Comp1L03			; Счёт не окончен (по T)	
	
			ld 		Tmp1,Z				; Получить номер события
			rcall 	SendTask			; послать в системную очередь задач
	
			ldi 	Tmp1,$FF			; = NOP (задача выполнена, таймер самоудаляется)
			st 		Z, Tmp1				; Clear Event

Comp1L03:	subi 	ZL,Low(-3)			; Skip Counter
			sbci 	ZH,High(-3)			; Z+=3 - переход к следующему таймеру
			dec 	Counter				; счетчик таймеров
			brne 	Comp1L01			; Loop	

			pop 	Counter				; восстанавливаем переменные
			pop 	ZH
			pop 	ZL

			pop 	Tmp1				; Восстанавливаем регистры
			out 	SREG,Tmp1			; 
			pop 	Tmp1
			.ENDM

;==============

Re: Непонятный код subi r17,high(1)

Добавлено: Пн дек 25, 2017 22:53:18
viiv
[uquote="ultexplorer",url="/forum/viewtopic.php?p=3268815#p3268815"]Как у единицы может быть старшая и младшая тетрады?[/uquote]
не тетрады, а байты. Старший и младший байт. Почему не может быть старшего байта? Вас смущает, что старший байт нулевой?

Мне непонятно, что же Вам непонятно :-)

Low(1) = 1
High(1) = 0

====
Low(256) = 0
High(256) = 1

Re: Непонятный код subi r17,high(1)

Добавлено: Пн дек 25, 2017 23:12:39
ultexplorer
Спасибо. Вроде начинает доходить...
Т.е. единица рассматривается как двухбайтная. В старшем байте 0b0000 0000, а в младшем 0b0000 0001
Выражение subi Tmp1,low(1) уменьшает значение в Tmp1 на единицу.
А выражение sbci Tmp1, high(1) означает, что от Tmp1 ничего не отнимается?

Re: Непонятный код subi r17,high(1)

Добавлено: Пн дек 25, 2017 23:16:48
viiv
[uquote="ultexplorer",url="/forum/viewtopic.php?p=3268838#p3268838"]А выражение sbci Tmp1, high(1) означает, что от Tmp1 ничего не отнимается?[/uquote]

Как это ничего? есть еще флаг переноса (который был сброшен/установлен предидущей командой)!

Re: Непонятный код subi r17,high(1)

Добавлено: Вт дек 26, 2017 10:03:29
BOB51
Только у АВРок для случаев двухбайтовой математики еще SBIW/ADIW имеются (диапазон константы 0-63).
Зачем дополнительный осложнямс? Разве что для экономии регистров...
:dont_know:

Re: Непонятный код subi r17,high(1)

Добавлено: Вт дек 26, 2017 17:32:48
НАПАЛМ
Изображение

Re: Непонятный код subi r17,high(1)

Добавлено: Ср дек 27, 2017 10:15:01
BOB51
Ну дык...
справедливо, ежли диапазон константы вычитания/сложения БОЛЕЕ 0-63 или оба числа есть содержимое регистров...
если необходимость сложения /вычитания двухбайтового числа с константой, определенной в пределах 0-63
(стандартные инкремент/декремент указателя адреса и/или 16-разрядного счетчика или чего подобного) удобнее использовать
в регистровой паре (любая из R25:R24, R27:R26, R29:R28, R30:R29) накопитель и команды SBIW rp,n ADIW rp,n...
тем более, что исключается контроль промежуточного переполнения, а условия по флагам (С и/или Z) соответствуют результату для 16-разрядного значения...
:roll: