0
\$\begingroup\$
R20 = (4 * R16 + 3 * R17 - R18) / 8

.org 0
start:
    ldi r16, 10
    ldi r17, 20
    ldi r18, 10   
    lsl r16
    lsl r16
    mov r20,r17
    lsl r20
    add r20,r17
    add r20, r16
    sub r20,r18
    asr r20
    asr r20
    asr r20
    
konec:
    rjmp konec

I created this program (ATMega169), to compute the expression and for the sake of accuracy I would need the operations to be performed in 16 bits. I know that there are R26 R27 registers that "act" as one, but I have no idea how to work with it. I need some study material or some kind of advice. Thank you in advance

\$\endgroup\$
4
  • 2
    \$\begingroup\$ study the ATmega datasheet ... there may also be a programming manual .... it is possible that there is s sequence of events to follow when dealing with 16 bit data transfers .... possibly operate on upper byte first and the lower byte on the next operation \$\endgroup\$
    – jsotola
    Commented Apr 22, 2021 at 0:38
  • \$\begingroup\$ There’s X,Y and Z which are register pairs 26:27,28:29,30:31. Mainly for pointer (indirect addressing) use. For your math, X,Y or Z won’t help you much. \$\endgroup\$
    – Kartman
    Commented Apr 22, 2021 at 1:18
  • \$\begingroup\$ And if I convert the registers to these x and y, then I don't get more range or any benefits? \$\endgroup\$
    – Aaron7
    Commented Apr 22, 2021 at 1:27
  • \$\begingroup\$ AVR doesn't have 16-bit arithmetic operations, you just do your operation on lower registers first, then use carry bit and do the higher part. Check addc and subc operations. \$\endgroup\$
    – floppydisk
    Commented Dec 30, 2022 at 12:20

2 Answers 2

1
\$\begingroup\$

The \$x\$ and \$y\$ and \$z\$ registers are mostly for indirect references: "These registers are 16-bit address pointers for indirect addressing of the data space." There aren't any ALU operations that support 16-bit because the ALU is an 8-bit ALU, not a 16-bit ALU. There's no escaping that requirement here.

\$\endgroup\$
0
\$\begingroup\$

Compute an exact integer value for (4a + 3b - c) / 8

Arithmetic is arithmetic - don't let using assembly transfix you.
The simplest thing that can be expected to do even for cores lacking mul/muls is stubbornly processing carries:

; Compute an exact integer value for (4a + 3b - c) / 8

.DEF a    = R16
.DEF b    = R17
.DEF c    = R18
.DEF sum  = R20
.DEF high = R21
.DEF zero = R19

    clr  zero
    clr  high
    mov  sum, a       ; sum =  a
    lsl  sum
    rol  high         ; sum = 2a
    lsl  sum
    rol  high         ; sum = 4a
    add  sum, b
    addc high, zero   ; sum = 4a +  b
    add  sum, b
    addc high, zero
    add  sum, b
    addc high, zero   ; sum = 4a + 3b
    sub  sum, c
    subc high, zero   ; sum = 4a + 3b - c
    lsr  high
    ror  sum          ; sum = trunc((4a + 3b - c) / 2)
    lsr  high
    ror  sum
    lsr  high
    ror  sum          ; sum = trunc((4a + 3b - c) / 8)
;   addc sum, zero    ; sum = round((4a + 3b - c) / 8)

(An optimising compiler's "interesting" way to fuse zeroing high and incorporating a carry:
subc high, high)

Trying not to first multiply by 4 and finally divide by (4*2): $$\begin{align} (4a + 3b - c) / 8 & = (4(a + b) - b - c) / 8 \\ & = (4(a + b)/4 - (b + c)/4) / 2 \\ \end{align}$$

; Compute an exact integer value for (4a + 3b - c) / 8 = (4(a+b)/4 - (b+c)/4) / 2

.DEF subtrahend = R21
.DEF bit8       = R19

    mov  sum, a          ; sum = a
    add  sum, b          ; C##sum = a + b  (C: carry flag; ##: concatenated)
    rol  bit8            ; save carry
    mov  subtrahend, b   ; subtrahend = b
    add  subtrahend, c   ; C##subtrahend = b + c
    sbrc subtrahend, 0   ; if one of the bits to shift out is 1,
    sbr  subtrahend, 1   ;  carry will be set as a result of the asr below
    ror  subtrahend      ; subtrahend = trunc((b + c) / 2) (conceptionally)
    asr  subtrahend      ; subtrahend = trunc((b + c) / 4) (conceptionally)
    subc sum, subtrahend ; sum = 4(a + b) / 4 - ceil((b + c) / 4) (hopefully)
    sbci bit8, 0
    ror  bit8
    ror  sum             ; sum = (4a + 3b -c) / 8 (hopefully)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.