Easyelectronics.ru

Электроника для всех
Текущее время: 22 янв 2021, 11:31

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 24 ] 
Автор Сообщение
 Заголовок сообщения: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 04 мар 2020, 22:28 
Заглядывает иногда

Зарегистрирован: 24 фев 2019, 14:46
Сообщения: 30
Всем привет. пишу на алгоритм билдере (но это не принципиально сейчас).
Пишу программу для работы с датчиком температуры, давления и влажности BME280. Так вот, свалилась проблемка. Необходимо производить умножение с 32 битными числами да еще и со знаком. С обычным умножением справился, а вот со знаковым - затормозил... Обычное умножение реализовано на основе операций умножения описанных в апноуте AVR201. А вот со знаковым забуксовал. Может кто делал это на ассемблере? Контроллер атмега8, желательно использование аппаратного перемножителя, так как есть ограничение на время обработки...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 04 мар 2020, 22:42 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
плиз


Вложения:
bmp085.rar [9.22 Кб]
Скачиваний: 80
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 05 мар 2020, 13:28 
Заглядывает иногда

Зарегистрирован: 24 фев 2019, 14:46
Сообщения: 30
ILYAUL писал(а):
плиз

Спасибо, но математика в этих датчиках малость отличается... температура и давление в моем датчике - трехбайтные (точнее 20бит), и преобразования понакрученней получаются - 32 битные с результатом в 64 бита (на давление точно). проблема - как организовать умножение 32 на 32 со знаком. Простое (без знака) - сделал, а это не могу.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 05 мар 2020, 15:55 
Заглядывает иногда

Зарегистрирован: 03 июл 2012, 19:16
Сообщения: 180
при умножении знаковых чисел выполняется корректировка результата в зависимости от знаков сомножытелей.
вот на пальцах для 8х8=16 (или 16х16=32 не помню уже :)
;Mul correction (signed!)
;MULX*MULY=PRODH:PRODL
;If MULX<0 then PRODH:PRODL=PRODH:PRODL+(-MULY):0000 <- add -MULY to PRODH
;If MULY<0 then PRODH:PRODL=PRODH:PRODL+(-MULX):0000 <- add -MULX to PRODH
;=>
;If MULX<0 then PRODH:PRODL=PRODH:PRODL-MULY:0000 <- sub MULY from PRODH
;If MULY<0 then PRODH:PRODL=PRODH:PRODL-MULX:0000 <- sub MULX from PRODH
ах да, это для дополнительного кода проверено


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 05 мар 2020, 23:06 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
Вы можете умножать без знака, если в старшем бите одного из множителей (1) то это отрицат. число, поэтому из 64 битного FF вычитаем результат и прибавляем 1


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 13 мар 2020, 22:58 
Старожил

Зарегистрирован: 02 июл 2010, 23:41
Сообщения: 473
1dimon1 писал(а):
ILYAUL писал(а):
плиз

Спасибо, но математика в этих датчиках малость отличается... температура и давление в моем датчике - трехбайтные (точнее 20бит), и преобразования понакрученней получаются - 32 битные с результатом в 64 бита (на давление точно). проблема - как организовать умножение 32 на 32 со знаком. Простое (без знака) - сделал, а это не могу.

Делайте обычное (без знака) умножение, а знак храните в отдельном бите.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 16 мар 2020, 19:36 
Старожил
Аватара пользователя

Зарегистрирован: 26 янв 2010, 21:55
Сообщения: 5576
Откуда: Уругвайская АССР
На сообществе висит "сложить и приумножить" - а это его знаковый вариант...
На выходе бит знака лежит во флаге T, то есть возможно +-65535
Код:
;**********************************************************************************************
; Signed conversion procedure
;**********************************************************************************************
Muladdsh:   ld   var10, y+   
      ld   var11, y+
      ld   var12, y+
      ld   var13, y+
; Проверка будущего знака результата умножения
      eor   var21, var13   ; сравниваем знаковые биты
      bst   var21, 7   ; запоминаем во флаге T знак будущего частного
      eor   var21, var13   ; восстанавливаем var21
; получение модуля множителей
      sbrs   var21, 7   ; Проверка знака конвертируемого числа
      rjmp   _mas_v1pos   ; если конвертируемое отрицательно
      ldi   r16, 0      ; преобразуем его
      ldi   r17, 0      ; в положительное
      sub   r16, var20   ; методом вычитания
      sbc   r17, var21   ; из ноля
      movw   var20, r16
_mas_v1pos:   sbrs   var13, 7   ; Проверка знака коэффициента K
      rjmp   _mas_v2pos   ; Конверсия в положительный при необходимости
      ldi   r16, 0
      sub   r16, var10
      mov   var10, r16
      ldi   r16, 0
      sbc   r16, var11
      mov   var11, r16
      ldi   r16,0
      sbc   r16, var12
      mov   var12, r16
      ldi   r16,0
      sbc   r16, var13
      mov   var13, r16
_mas_v2pos:   rcall   Mul24x16uh   ; Var1{01234} = var1{012} * var2{01}
      rol   var11
      rcall   round24      ; Округление после деления
; Загрузка офсета      
      ld   var20, y+
      ld   var21, y+      
; Ветвление, исходя из знака результата умножения
; Возможны 4 случая:
; 1) положительный+положительный. возможно переполнение сверху при умножении или сложении
; 2) положительный+отрицательный. Возможно переполнение сверху при умножении, или переход через ноль при сложении
; 3) отрицательный+положительный. возможно переполнение снизу на этапе умножения, или переход через ноль при сложении
; 4) отрицательный+отрицательный. переполнение снизу при умножении или сложении.
      ldi   r16,0
      brtc   _mas_repos   ; проверка - должен ли результат быть отрицательным?
; здесь - результат умножения отрицательный
      sbrs   var21, 7
      rjmp   _mas_negpos
; здесь - отрицательный результат умножения и отрицательный офсет. Возможно переполнение снизу.
      clr   var10
      clr   var11
      sub   var10, var20   ; меняем знак офсета
      sbc   var11, var21
      add   var12, var10
      adc   var13, var11
      adc   var14, r16
      brcs   _sicon_max   ; перенос после сложения
_sicnchkovf:   tst   var14
      breq   _sicon_exit   ; проверка на переполнение
_sicon_max:   ldi   r16, 0xff   ; Ограничение сверху/снизу
      mov   var12, r16
      mov   var13, r16
      rjmp   _sicon_exit
; здесь - отрицательный результат умножения и положительный офсет. Возможно переполнение снизу(сверху по модулю) или изменение знака.
_mas_negpos:   sub   var12, var20
      sbc   var13, var21
      sbc   var14, r16
      brcc   _sicnchkovf   ; проверка перехода через 0, смена знака
; здесь - произошел переход через 0 при вычитании. результат имеет противоположный знак.
      clt         ; смена знакового флага
_sicnchsgn:   sub   r16, var12
      mov   var12, r16   ; смена знака результата
      ldi   r16, 0
      sbc   var13, r16
      mov   var13, r16
      rjmp   _sicon_exit
; Положительный результат умножения
_mas_repos:   sbrs   var21, 7   ; проверка знака офсета
      rjmp   _mas_pospos
; Здесь - положительное число после умночения и отрицательный офсет. Возможно переполнение, возможен переход через 0
      clr   var10
      clr   var11
      sub   var10, var20   ; меняем знак офсета
      sbc   var11, var21
      sub   var12, var10   ; отнимаем от произведения модуль офсета
      sbc   var13, var11
      sbc   var14, r16
      brcc   _sicnchkovf   ; нет займа, знак не сменился, проверяем на переполнение
; смена знака результата после сложения. Результат отрицательный, и ложно обозначен как положительный
      set         ; меняем знаковый флаг
      rjmp   _sicnchsgn   ; меняем знак результата   
_mas_pospos:   
; Здесь - положительное число после умночения и положительный офсет. Возможно только переполнение.
      add   var12, var20
      adc   var13, var21
      adc   var14, r16
      brcs   _sicon_max   ; перенос после сложения
      brne   _sicon_max   ; переполнение после сложения
_sicon_exit:   ret


Mul24x16uh.asm
(mul 24 * 16 bit Unsigned Hardware_acc)
Код:
;***************************************************************************
; Var1x{01234} = var1x{012} * var2x{01}
;***************************************************************************
Mul24x16uh:   ldi   r16,0
      mul   var12, var21   ; b*x
      mov   var13, r0
      mov   var14, r1

      mul   var12, var20   ; b*y
      MOV   var12, R0
      add   var13, R1
      adc   var14, r16   ; zero

      mul   var11, var21   ; c*x
      add   var12, R0
      adc   var13, R1
      adc   var14, r16   ; zero
      
      mul   var11,var20   ; c*y
      mov   var11,R0
      add   var12,R1
      adc   var13, r16   ; zero
      adc   var14, r16   ; zero

      mul   var10,var21   ; d*x
      add   var11,R0
      adc   var12,R1
      adc   var13, r16   ; zero
      adc   var14, r16   ; zero

      mul   var10, var20   ; d*y
      mov   var10, R0
      add   var11, R1
round24:   adc   var12, r16   ; zero   - и повторный вход для выполнения округления при необходимости
      adc   var13, r16   ; zero
      adc   var14, r16   ; zero
      ret

_________________
Без гнева и жестокости, сегодня Смерть взмахнёт косой, и ангел тайными дорогами мой милый Кубик унесёт с собой.


Последний раз редактировалось Горнист 16 мар 2020, 21:38, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 16 мар 2020, 21:02 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
У меня в загашниках нашлось это. К сожалению не помню у кого взял. Но автору респект


Вложения:
div.txt [10.5 Кб]
Скачиваний: 127
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 17 мар 2020, 17:49 
Заглядывает иногда

Зарегистрирован: 24 фев 2019, 14:46
Сообщения: 30
Всем огромное спасибо, задачу решил, может и не очень красиво, но работает. К сожалению чистый ассемблерный код выложить не могу, так как пишу в Алгоритм Билдере, могу выложить в нем.
Следующая задача - 64 битное умножение :), в том числе и знаковое, но это пока не горит.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 17 мар 2020, 20:08 
Старожил
Аватара пользователя

Зарегистрирован: 26 янв 2010, 21:55
Сообщения: 5576
Откуда: Уругвайская АССР
64 бита концептуально не отличается от 32х бит.

_________________
Без гнева и жестокости, сегодня Смерть взмахнёт косой, и ангел тайными дорогами мой милый Кубик унесёт с собой.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 18 мар 2020, 12:15 
Заглядывает иногда

Зарегистрирован: 24 фев 2019, 14:46
Сообщения: 30
Горнист писал(а):
64 бита концептуально не отличается от 32х бит.

Только с памятью надо разобраться, где хранить промежуточные данные... и чтобы это относительно быстро работало...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 18 мар 2020, 13:32 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
Дайте лист с формулами расчёта для BME280


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 18 мар 2020, 14:23 
Заглядывает иногда

Зарегистрирован: 24 фев 2019, 14:46
Сообщения: 30
ILYAUL писал(а):
Дайте лист с формулами расчёта для BME280


Все строго по даташиту, пункт 4.2.3:

Привожу кусочек из даташита для температуры.
Show

где собственно >> - сдвиг вправо, а цифра после этого знака - число сдвигов.
<< - сдвиг влево
Числа 32 разрядные. Кстати предварительные деления с целью уменьшить разрядность - плохая идея - очень сильно портиться результат (проверял в екселе).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 31 мар 2020, 17:28 
Заглядывает иногда

Зарегистрирован: 24 фев 2019, 14:46
Сообщения: 30
Продолжаю работу с датчиком BME280, перешел к давлению и...
Итак, я уперся. :( .Вероятная причина - незнание мной особенностей работы в с++ и им подобных (ну не изучал, от слова совсем). в даташите приведены
собственно причина - если задаются значения в виде:
var2 = (((var1>>2) * (var1>>2)) >> 11 ) * ((BME280_S32_t)dig_P6)
, где все Var тоже int32_t (все знаковые), я ответ должен получить в 64 битном формате или в 32 битном? если в 32 битном то в ответе старшие данные? Извините за вопрос... если он глупый.
Результат не совпадает с реальностью и рабочих примеров для сравнения (на ассемблере) я не нашел, а в ардуино заниматься декомпиляцией.... еще то развлечение.
с температурой как-то проще вышло...
в спойлере кусок кода отвечающий за расчет давления...
Show


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 31 мар 2020, 18:37 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
var2 = (((var1>>2) * (var1>>2)) >> 11 ) * ((BME280_S32_t)dig_P6)= (((var1/2)*(var2/2))/2^11)*((BME280_S32_t)dig_P6) . 2^11=2048. var1/2 - Сдвиг вправо 1 раз, флаг С должен быть сброшен


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 31 мар 2020, 18:43 
Заглядывает иногда

Зарегистрирован: 24 фев 2019, 14:46
Сообщения: 30
ILYAUL писал(а):
var2 = (((var1>>2) * (var1>>2)) >> 11 ) * ((BME280_S32_t)dig_P6)= (((var1/2)*(var2/2))/2^11)*((BME280_S32_t)dig_P6)

что означают стрелочки мне известно (сдвиги влево в право или умножение или деление на 2), меня интересует полученная в итоге разрядность, то есть при умножении 32 битного числа на 32 битное число - здесь мы должны получить по идее 64 бит, или только 32 бита со значением старших разрядов или только младшие? Я этот момент как то не догоняю.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 31 мар 2020, 18:52 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
https://server.179.ru/tasks/cpp/total/121.html


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 31 мар 2020, 20:22 
Заглядывает иногда

Зарегистрирован: 24 фев 2019, 14:46
Сообщения: 30
ILYAUL писал(а):
https://server.179.ru/tasks/cpp/total/121.html

по даташиту, указанный код для 32 битных Cortex-M3:
In the table below an overview is given for the number of clock cycles needed for compensation
on a 32 bit Cortex-M3 micro controller with GCC optimization level -O2. This controller does not
feature a floating point unit, thus all floating-point calculations are emulated. Floating point is
only recommended for PC application, where an FPU is present and these calculations are
performed drastically faster.

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

32в*32в=32в
или
32в*32в=64в
?
по расчетам - большинство результатов лезут далеко за 32 бита.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 31 мар 2020, 20:38 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
32в*32в=64в


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 13 апр 2020, 22:20 
Заглядывает иногда

Зарегистрирован: 24 фев 2019, 14:46
Сообщения: 30
Всем спасибо, все получилось.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 14 апр 2020, 02:15 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
Cпасибо это много, давай код в студию :)))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 15 апр 2020, 11:41 
Заглядывает иногда

Зарегистрирован: 24 фев 2019, 14:46
Сообщения: 30
ILYAUL писал(а):
Cпасибо это много, давай код в студию :)))

Три варианта... в формате алгоритм билдер.
Готовый нех., чисто ассемблеровского кода нет. Есть только листинг, но его править придется ручками...
Ссылка на другой форум, посвященный и алгоритм билдеру в частности, где это уже все выложено.
Какой вариант лучше?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 15 апр 2020, 15:49 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
Привет! Дай ссылку , плиз


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: умножение 32 битных чисел со знаком написать на ассемблере.
СообщениеДобавлено: 15 апр 2020, 22:54 
Заглядывает иногда

Зарегистрирован: 24 фев 2019, 14:46
Сообщения: 30
ILYAUL писал(а):
Привет! Дай ссылку , плиз

Здесь http://www.forum.getchip.net/viewtopic.php?f=18&t=1033


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 24 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB