Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Микроконтроллеры (MCU) и микропроцессоры (MPU) > задача по MK51


Автор: :)PROD[; 3.12.2006, 22:00
Здравствуйте.
Дали задание – написать на ассемблере программу для МК51 (эмулятор AVSim51).
Задача: поместить в регистр B среднее арифметическое массива 8-ми разрядных двоичных чисел в адресах 20H-2FH.

Все бы хорошо, но при сложении 16ти однобайтных чисел (если брать максимально-допустимое для них значение) может получиться 12ти разрядное число, и напрямую командой DIV AB его не разделить.
Есть идея перевести сумму из двоичной в двоично-десятичную систему, записать в DPTR (тысячи и сотни в DPH,а десятки и единицы в DPL), потом их обратно в двоичную систему и уже потом делить по частям. Вот только программка получается уж больно здоровой.
Нет ли более простого способа решить?
Заранее спасибо

Автор: LessNik 4.12.2006, 10:00
Самый простой способ - написать на Cи, а потом в листинге посмотреть ассемблерный код и сказать, что мол типа сам написал smile Ну а если очень хочется написать самому на ассемблере, то можешь сначала делить каждое число на знаменатель, а уж потом складывать. (x1+x2+x3+...+xn)/n=x1/n +x2/n +x3/n + ... + x4/n. Справишься байтовыми регистрами.


Цитата(:)PROD[; @  3.12.2006,  22:00 Найти цитируемый пост)
Есть идея перевести сумму из двоичной в двоично-десятичную систему, записать в DPTR (тысячи и сотни в DPH,а десятки и единицы в DPL), потом их обратно в двоичную систему и уже потом делить по частям


Чё-то ты намудрил.

Автор: maxim1000 4.12.2006, 12:27
Цитата(LessNik @  4.12.2006,  09:00 Найти цитируемый пост)
(x1+x2+x3+...+xn)/n=x1/n +x2/n +x3/n + ... + x4/n

если деление нацело (а оно нацело), то массив из (к примеру) 2-ек даст среднее 0, что не очень хорошо

в данном случае количество элементов 16, так что деление можно заменить сдвигом
если есть возможность работать с 16-разрядным аккумулятором, и вытащить из него биты 4..11, то, пожалуй, это - оптимальный вариант

если можно работать только с байтами, то подойдёт такое (модификация предложенного "поразрядного способа", только используется 16-ричная система - оптимальнее получается):

отдельно усредняем старшие: сначала сдвигаем их на 4 вниз (это можно сделать без потерь, т.к. у старших четвёрок младшие 4 бита нулевые), а потом складываем

отдельно усредняем младшие - просто складываем (переполнения не будет) и сдвигаем вниз на 4 (потери будут, но как раз от этих потерь никак не избавиться)

ну и складываем результаты

Автор: :)PROD[; 5.12.2006, 06:27
задача решена.
загоняем сумму 16ти элементов в DPTR и сдвигаем на 4 бита влево. либо обмениваем тетрады по принципу  
SWAP DPL
ANL DPL,#00FF
SWAP DPH
ANL DPH,#FF00
ORL DPH,DPL

идея LessNik возможно неплоха для Си, на асме либо будет давать большие погрешности, либо не будет работать вообще.

Всем спасибо smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)