Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Асмик Гаряка
Статус: Советник
Рейтинг: 10964
∙ повысить рейтинг »
Коцюрбенко Алексей aka Жерар
Статус: Советник
Рейтинг: 3992
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 1762
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1539
Дата выхода:15.04.2013, 20:00
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:58 / 21
Вопросов / ответов:1 / 1

Консультация # 187263: Здравствуйте, уважаемые эксперты! Для учебной цели получил задания сложить два числа с плавающей точкой из диапазона [-9..9] с точностью до 4х знаков. Программу нужно написать на ассемблере для процессора архитектуры Тесей "КР1878ВЕ1". Нашел алгоритм для работы с плавающей точкой на сайте http://nauchebe.net/2011/03/operacii-nad...


Консультация # 187263:

Здравствуйте, уважаемые эксперты!
Для учебной цели получил задания сложить два числа с плавающей точкой из диапазона [-9..9] с точностью до 4х знаков. Программу нужно написать на ассемблере для процессора архитектуры Тесей "КР1878ВЕ1".

Нашел алгоритм для работы с плавающей точкой на сайте http://nauchebe.net/2011/03/operacii-nad-chislami-s-plavayushhej-tochkoj-mk-avr/

Так как на ассемблере ни разу не писал, то не могу понять синтаксис, структуру и как складывать числа, у которых разрядность больше 8 бит. Есть сложность с условиями. При возможности добавьте пожалуйста комментарии. Спасибо!

Дата отправки: 07.04.2013, 19:23
Вопрос задал: Игорь (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, Игорь!
Вот Вам программа для процессора КР1878ВЕ1
Программа является переводом программы из приведенной Вами ссылки с языка ассемблера AVR на язык КР1878ВЕ1.
Формат вещественного числа уменьшен с 4-х байт до 3-х, за счет усечения младших бит мантиссы.
Для решения поставленной задачи этого вполне достаточно.
Будут вопросы, спрашивайте в мини-форуме...

Код :
;дадим для
удобства имена используемых регистров
#define	pA	%a0	;первый байт первого числа - порядок
#define	mAH	%a1	;второй байт первого числа - старший байт мантиссы
#define	mAL	%a2	;третий байт первого числа - младший байт мантиссы
#define	pB	%b0	;первый байт второго числа - порядок
#define	mBH	%b1	;второй байт второго числа - старший байт мантиссы
#define	mBL	%b2	;третий байт второго числа - младший байт мантиссы
#define	acc	%c0	;рабочий регистр - аккумулятор
#define	sign	%c1	;регистр для хранения знака числа (вместе с порядком)

	jmp	Start		;<0> Начальный пуск
	jmp	Err		;<1> Сторожевой таймер
	jmp	Err		;<2> Сбой программы (стеки,память)
	jmp	Err		;<3> Таймер A
	jmp	Err		;<4>
	jmp	Err		;<5>
	jmp	Err		;<6> Порт A
	jmp	Err		;<7>
	jmp	Err		;<8>
	jmp	Err		;<9>
	jmp	Err		;<10>
	jmp	Err		;<11>
	jmp	Err		;<12>
	jmp	Err		;<13>
	jmp	Err		;<14>
	jmp	Err		;<15>

Err:	jmp	Err		;все ошибки приведут сюда

Start:				;старт программы
	cst	8		;запрещаем прерывания (IE=0)
	ldr	#a,40h		;Установка сегмента A
	ldr	#b,48h		;Установка сегмента B
	ldr	#c,50h		;Установка сегмента C
;первое число  = 5.75 = 0.1000000|1.0111000|00000000
	movl	pA,40h		;знак + 7 старших бит порядка
	movl	mAH,0b8h	;мл бит порядка + 7 старших бит мантиссы 
	movl	mAL,00h		;8 младших бит мантиссы
;второе число = 2.25 = 0.1000000|0.0010000|00000000
	movl	pB,40h		;знак + 7 старших бит порядка
	movl	mBH,10h		;мл бит порядка + 7 старших бит мантиссы 
	movl	mBL,00h		;8 младших бит мантиссы

	jsr	AddF		;складываем

Exit:	jmp	Exit		;все решено, крутимся на месте.

;функция сложения двух вещественных чисел
AddF:
;проверим на совпадение знаков чисел
;нас интересует только старший бит - бит знака
	mov	acc, pA		;acc = pA
	xor	acc, pB		;acc = pA xor pB
	btth	acc, 1000b	;проверим старший бит результата	
	jeq	AddF1		;0, когда знаки одинаковые - идем дальше
				;иначе
	bish	pB, 1000b	;меняем знак у В
	jmp	SubF		;и идем на вычитание! (A+(-B)=A-(+B))

AddF1:	jsr	cp_B_0		;сравним В с 0
	jeq	Return		;результат в А

	jsr	cp_A_0		;сравнение A с 0
	jne	AddF2		;оба не 0 - идем дальше
				;А=0, значит результатом будет В
	jsr	swapAB		;обмен A и В
	rts			;результат в А

AddF2:	mov	sign, pB	;сохранение знака вместе с порядком рВ.7

;приведем числа к удобному для использования виду:
;порядок теряем (он сохранен и будет учтен позже), 
;порядок полностью в байте порядка.
;в старшем байте мантиссы добавляем подразумеваемую старшую единицу
	jsr	rec		;восстановление первого числа в А
	jsr	swapAB		;теперь А=В, а В=А
	jsr	rec		;восстановление второго числа в А

;смотрим, какое из чисел больше, для этого сравниваем порядки чисел
	mov	acc, pA		;вычитание порядков acc = pА - pB
	sub	acc, pB
	jns	AddF3		;переход, если больше 0 (второе(в А) больше первого(в В)),
	jsr	swapAB		; иначе обмен и
	mov	acc, pA		; снова вычитание acc = pA - pB
	sub	acc, pB		

AddF3:
;меньшее число в В, большее - в А
;в acc имеем разность порядков чисел, Z=1, если 0, т.е. порядки равны
	jeq	AddF6		;переход, если порядки равны
;определим, есть ли потеря значимости, 
;т.е. насколько одно число больше второго.
;если больше чем на 15, то меньшее число при сдвиге просто обнулится
;и результат будет равен большему числу
	cmpl	acc, 16		;сравниваем 
	jc	AddF4		;есть, что складывать
	jmp	AddF7		;переход при потере значимости

AddF4:	mov	pA, acc		;разность порядков в рА
	jsr	swapAB		;разность теперь в рВ, мантисса большего числа в mB

;выравним порядки чисел, для этого сдвинем меньшее число (в А) на число бит,
;равное разности порядков
AddF5:	jsr	shift		;сдвиг в регистрах mА
	inc	pA		;увеличиваем порядок меньшего числа
	dec	pB		;уменьшаем разность порядков 
	jne	AddF5

;порядки выравнены
AddF6:	add	mAL, mBL	;сладываем мл байты мантисс
	adc	mAH		;учтем перенос
	add	mAH, mBH	;ст байты мантисс

;проверим, надо ли число нормализовать, т.к. у числа должна быть целая часть, равная 1
;исходное число с единицей в старшем разряде
;если не будет переноса в бит С, то число осталось нормализованным
	jnc	AddF7		;проверка нарушения нормализации
;есть нарушение, правим
	inc	pA		;корректируем порядок
;есть опасность переполнения, когда порядок изменится с ffh на 00h, 
;проверим
	stc			;взведем на всякий случай флаг ошибки
	jeq	Return		;выход с флагом переполнения С

	jsr	shift		;корректируем мантиссу сдвигом вправо

AddF7:	jsr	pack		;форматирование результата 
Return:	rts			;выход

;------------------------------------------------------
;вычитание А-В
SubF:	mov	acc, pA		;сравнение знаков чисел
	xor	acc, pB
	btth	acc, 1000b	;проверим старший бит результата	
	jeq	SubF1		;0, когда знаки одинаковые - идем дальше
				;иначе
	bish	pB, 1000b	;изменение знака
	jmp	AddF		;считаем сумму A-(-B)=A+B

SubF1:	jsr	cp_B_0		;проверка В на 0
	jeq	Return		;результат равен А

	jsr	cp_A_0		;проверка A на 0
	jne	SubF2		;оба не 0, идем дальше

	jsr	swapAB		;обмен операндов
	bish	pA, 1000b	; со сменой знака результата
	rts			;результат A=-B

SubF2:	mov	sign, pA	;сохраняем знак

	jsr	rec		;восстановление числа А
	jsr	swapAB		;теперь в рА порядок 2-го числа
	jsr	rec		;восстановление числа В в регистрах А

;определим, какое число больше
	mov	acc, pB		;из порядка 1-го вычитаем
	sub	acc, pA		; порядок 2-го
	jne	SubF3		;числа разные

	cmp	mBH, mAH	;при равенстве порядков
	jne	SubF3		; сравниваем мантиссы

	cmp	mBL, mAL
	jne	SubF3

	clr	pA		;если числа равны,
	clr	mAH		; результат равен 0
	clr	mAL
	rts

SubF3:	jnc	SubF4		;переход, если 1-е число
				; (оно в pB,mB) больше, 
	jsr	swapAB		; иначе обмен числами
	btgh	sign, 1000b	; и изменение знака в sign

SubF4:	mov	acc, pB		;снова вычитание порядков
	sub	acc, pA
	jeq	SubF7		;переход при одинаковых порядках

	cmpl	acc, 16		;проверим на потерю значимости
	jc	SubF6		;идем дальше

	jsr	swapAB		;передача большего числа
				; в (pA,mA) перед 
	jmp	SubF9		; форматированием результата

SubF6:	jsr	shift		;сдвиг мантиссы меньшего числа
	dec	acc		; в mА, пока
	jne	SubF6		; разность порядков не равна 0

;Вычитание мантисс и сохранение разности в mА

SubF7:	sub	mBL, mAL	;мл б мантиссы
	mov	mAL, mBL
	sbc	mBH		;учитываем заем
	sub	mBH, mAH	;ст б мантиссы
	mov	mAH, mBH
	mov	pA, pB		;передача порядка результата в pA

SubF8:	btth	mAH, 1000b	;проверка нарушения нормализации
	jnz	SubF9		;переход, если нарушения нет,
	dec	pA		; иначе, не сдвигая мантиссу,
	jc	SubQuit		;при антипереполнении выходим
				; с флагом C=1, иначе
	shl	mAL		; сдвигаем мантиссу mА влево 
	rlc	mAH
	cst	1		; и сбрасываем флаг C
	jmp	SubF8		;повторяем проверку

SubF9:	jsr	pack		;форматируем результат

SubQuit:rts			;выход из процедуры вычитания

;-------------------------------------------
;вспомогательные подпрограммы
;-------------------------------------------
;Восстановление операнда из базового формата 
rec:	shl 	mAH		;младший разряд порядка (ст бит байта) в С
	rlc 	pA		;восстановление порядка
	shr 	mAH		;сдвиг вправо мантиссы
	bish	mAH, 1000b	;восстановление скрытой 1
	rts

;Упаковка в базовый формат 
pack:	clr	pB		;здесь сформируем байт с младшим битом 
				; порядка на старшем месте
	shl	sign		;ст бит (знак) уходит в С
 	rrc	pA		;вводим знак в рА.7, мл бит в С
	rrc	pB		;вводим мл бит порядка на место ст бита pB
	bich	mAH, 1000b	;сначала обнулим старший бит ст байта мантиссы
	or	mAH, pB		;пишем его на свое место
	rts

;Обмен операндов 
swapAB:	xor	pA, pB		;обмен регистров
	xor	pB, pA		; рА и рВ
	xor	pA, pB		; за три операции

	xor	mAL, mBL
	xor	mBL, mAL
	xor	mAL, mBL

	xor	mAH, mBH
	xor	mBH, mAH
	xor	mAH, mBH
	rts

;сравнение А(В) с 0
cp_A_0:	mov 	acc, pA
	or	acc, mAH
	or	acc, mAL	;при A=0 возвращает флаг Z=1
	rts			;при A!=0 – Z=0

cp_B_0:	mov	acc, pB
	or	acc, mBH
	or	acc, mBL	;при B=0 возвращает флаг Z=1
	rts			;при B!=0 – Z=0

;Сдвиг вправо 24-разрядной мантиссы mA 
shift: 	shr	mAH
	rrc	mAL
	clc
	rts

	.END


Вот здесь подправленный код из приведенной Вами ссылки для AVR: avr.rar (3.1 кб)

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 14.04.2013, 04:36

5
Спасибо за помощь!
-----
Дата оценки: 15.04.2013, 13:53

Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!



В избранное