[an error occurred while processing this directive] [an error occurred while processing this directive]
Хотя, попробуем прямо сюда
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)
[an error occurred while processing this directive] [an error occurred while processing this directive]

Отправлено HoBo 15 мая 2002 г. 20:07
В ответ на: Господа, подскажите ассемблерную библиотеку АВР 16битовой знаковой арифметики с умножением и делением отправлено erema 15 мая 2002 г. 11:43


;--------------------------------------------------------------
; S_MUL_L02
; 'short' (i.e. 16 bit) multiplication, both signed and unsigned
; On call: PW = multiplier, QW = multiplicand
; Returns 16-bit result in PW.
; IMPORTANT: If possible, put smallest (in absolute sense) number in PW.
;
; Destroys: P0 P1 Q0 Q1 T0 T1
;
; SIZE: 32 bytes
;

MODULE ?S_MUL_L02
PUBLIC ?S_MUL_L02
RSEG CODE:CODE:NOROOT(1)

?S_MUL_L02:
CLR T0 ; Clear accumulator
CLR T1 ; - " -
A21: CPI P0,0 ; Will always clear carry. Sets Z only if P0=0.
CPC P0,P1 ; If equal, old setting of Z is retained
BREQ X21 ; Branch if multiplier exhausted (both P0 and P1 are 0)
LSR P1 ; Shift multiplier right
ROR P0
BRCC B21 ; Branch if bit shifted out from multiplier was 0
ADD T0,Q0 ; Add multiplicand
ADC T1,Q1
B21: LSL Q0 ; Shift multiplicand left
ROL Q1
RJMP A21
X21: MOV P0,T0
MOV P1,T1
RET
;-------------------------------------------------------------
; SS_DIVMOD_L02
; 'short' (i.e. 16 bit) signed division and modulo
; On call: PW = dividend (i.e. number to be divided by divisor)
; QW = divisor
; On return: PW = quotient, QW = remainder
;
; NOTE: This subroutine calls US_DIVMOD_L02
;
; Flag NEG_QUOTE uses bit 0 of Z1
; Flag NEG_REM uses bit 1 of Z1
;
; Destroys: P0 P1 Q0 Q1 T0 T1 Z0 (via US_DIVMOD_L02) Z1
;
; SIZE: 46 bytes

MODULE ?SS_DIVMOD_L02
PUBLIC ?SS_DIVMOD_L02
IMPORT ?US_DIVMOD_L02
RSEG CODE:CODE:NOROOT(1)

?NEG_Q:
NEG Q1
NEG Q0
SBCI Q1,0
RET

?SS_DIVMOD_L02:
CLR Z1 ; Used for flags NEG_QUOTE and NEG_REM
TST Q1 ; Is divisor negative ?
BRPL A26 ; No
ORI Z1,1 ; Set NEG_QUOTE
RCALL ?NEG_Q ; Negate divisor
A26: TST P1 ; Is dividend negative ?
BRPL B26 ; No
COM Z1 ; Invert NEG_QUOTE and set NEG_REM
RCALL ?NEG_P ; Negate divisor
B26: XCALL ?US_DIVMOD_L02
SBRC Z1,0 ; Skip if not NEG_QUOTE
RCALL ?NEG_P ; Negate quotient
C26: SBRC Z1,1 ; Skip if not NEG_REM
RJMP ?NEG_Q ; Negate remainder
X26: RET

?NEG_P:
NEG P1
NEG P0
SBCI P1,0
RET


Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru