## Comparison 16bits ASM ATmega328

24 posts / 0 new
Author
Message

Guys, as I'm a student of AVR ATmega328 and I'm programming in ASM.

I have the following question

I have a value of 16bits (R10: R11) (High: Low) and would like to compare with another value of 16bits (R12: R13) (High: Low).

If R10: R11 Equals R12: R13 Does Nothing
If R10: R11 is larger than R12: R13 increments R14: R15
If R10: R11 is smaller than R12: R13 decrees R14: R15

I can't handle this routine, work with 16bits, 2 registers

Can someone help me

Well normally in a little endien processor like the AVR, the low byte is in the low reg, and the high byte is in the high reg, so are you sure about your values?

Then you need to know are the values signed or unsigned values?

Jim

Its been awhile since I did any ASM so I'll let the C compiler show how it does it in asm: using unsigned values

```(0022)         if( A == B)
_main:
0006D 9020 0102 LDS	R2,_B
0006F 9030 0103 LDS	R3,_B+1
00071 9040 0100 LDS	R4,_A
00073 9050 0101 LDS	R5,_A+1
00075 1442      CP	R4,R2
00076 0453      CPC	R5,R3
00077 F409      BNE	0x0079
(0023)             PORTB = A;
00078 B845      OUT	0x05,R4```

So in this example B is in R2:R3, A is in R4:R5, notice the low bytes are compared then the high bytes.

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get \$5 free gold/silver https://www.onegold.com/join/713...

Last Edited: Sun. Nov 10, 2019 - 06:24 PM

"compare the two high bytes, then compare the two low bytes using the barrow flag."

When I started programming AMTmega8 in assembly, I made a list of the basic instructions and another for the I/O registers on excel.

I usually have a look at these two lists while writing a code, just to be sure since my memory is rather short lately (I am 70).

I attached the worksheet as it is. I hope you will like it even a little

## Attachment(s):

I will follow the AVR standard

If R10: R11 (L: H) is equal to R12: R13 (L: H) do nothing

If R10: R11 (L: H) is greater than R12: R13 (L: H) increments R14: R15 (low: High)

If R10: R11 (L: H) is less than R12: R13 (L: H) decrees R14: R15 (L: H)

Unsigned values

I usually wrote your lines as:

If R11:R10 (H:L) is equal to R13:R12 (H:L) do nothing

If R11:R10 (H:L) is greater than R13:R12 (H:L) increment R15:R14 (high:low)

If R11:R10 (H:L) is less than R13:R12 (H:L) decrease R15: R14 (H:L)

There are 2 compare instructions, CP and CPC (as on #2).

Also there are conditional instructions; as BREQ (branch if equal), BRSH (branch if same or higher) and BRLO (branch if lower). You will need to use them all (well just 2 conditional instructions... don't forget RJMP).

Last Edited: Sun. Nov 10, 2019 - 07:10 PM

Any kind of compare is really just a subtraction. If Z is set at the end the two were equal if C is set the one being subtracted is larger than the one it us subtracted from. If neither us set it is larger.

Thing is that apart from SBIW (which doe not help here) the AVR doesn't do 16 but subtracts so you need to double up with a SUB then an SBC.

clawson wrote:
Any kind of compare is really just a subtraction.

Exactly, CP and CPC are just like SUB and SBC, except that the result is discarded, and only the flags are changed.

So, comparing multibyte values is just like adding or subtracting, first you perform the regular operation (ADD/SUB/CP) on the lowest order byte, then the operation with carry (ADC/SBC/CPC) on the successive higher order bytes.

```;Compare immediate a register pair with a value. registers r16-r30
;
.MACRO CPIW 		;Arguments: Register pair,  Data, scratch register (ie zl,zh,1234,temp),
ldi	@3,high (@2)
cpi	@0,low (@2)
cpc	@1,@3
.ENDMACRO

;Compare 2 register pairs. any registers
;
.MACRO CPRW 		;Arguments: Register pairs (ie zl,zh,xl,xh), any register pair
cp	@0,@2
cpc	@1,@3
.ENDMACRO
```

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

To OP,

Please note (for the next time perhaps) that there are 2 main reasons for which you didn't get the full answer/code you are looking for:

[1] You didn't present here any code with which you started to solve your exercise.

[2] There are many ways to implement it.

aless2056 wrote:
compare

Is that just to see if they are equal or not, or also to determine which is largest/smallest ... ?

Top Tips:

1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...

If R10: R11 Equals R12: R13 Does Nothing
If R10: R11 is larger than R12: R13 increments R14: R15
If R10: R11 is smaller than R12: R13 decrees R14: R15

clawson wrote:
If Z is set at the end the two were equal if C is set the one being subtracted is larger than the one it us subtracted from. If neither us set it is larger.

There is an AVR app note on 16-Bit Arithmetics.

https://www.microchip.com/wwwApp...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

you can prob make  it better with bacon

```
ldi ZL, low(1)
ldi ZH, high(0)
cp r11, r13
cpc r10, r12
breq be_done
brsh do_sum
ldi ZL, low(-1)
ldi ZH, high(-1)
be_done: blah blah blah```

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Tue. Nov 12, 2019 - 08:37 AM

There is an AVR app note on 16-Bit Arithmetics.

;* Title:        16-bit Arithmetics
;* Version:        1.1
;* Last updated:    97.07.04
;* Target:        AT90Sxxxx (All AVR Devices)

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Now let's say that I have register R20 and I want to set bit 0 and bit 2 and after a while I want to set bit 4 as well and reset bit 2.
Don't have a command like SBI or CBI for registers R0 ~ R31?
I saw that you have SBR and CBR, but you don't have a specific command to set a bit in a general purpose register.

Last Edited: Fri. Nov 15, 2019 - 12:43 AM

SBI or CBI for registers R0 ~ R31?

The I stands for I/O bits.

I saw that you have SBR and CBR,

The R stands for register bits. However they only work with registers 16-31, see the  AVR Instruction Set Manual.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

I saw that you have SBR and CBR, but you don't have a specific command to set a bit in a general purpose register.

You can use  SBR/CBR in r16-r31... you can use and & or in registers r00-r15 (with an extra command to load the needed mask)

what do you consider general purpose:

– 131 Powerful Instructions – Most Single Clock Cycle Execution
– 32 x 8 General Purpose Working Registers

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Fri. Nov 15, 2019 - 04:38 AM

avrcandies wrote:
I saw that you have SBR and CBR, but you don't have a specific command to set a bit in a general purpose register.

Specific? [where is that devil emoticon]

avrcandies wrote:
– 131 Powerful Instructions

lol -- aren't there really about 78 instructions, and a bunch of pseudonyms?

 75 according to Cliff, but ralphd may not agree https://www.avrfreaks.net/commen... ]

SBR and CBR are aliases for ORI and ANDI, right?  Yes, the lower registers have some limitations, but conceptually isn't ORI and [~]ANDI to carry out

aless2056 wrote:
Now let's say that I have register R20 and I want to set bit 0 and bit 2 and after a while I want to set bit 4 as well and reset bit 2.

js wrote:

With regard to the instructionbs in question, has the AVR instruction set changed since the first databook?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Fri. Nov 15, 2019 - 01:21 PM

I saw that you have SBR and CBR, but you don't have a specific command to set a bit in a general purpose register.

That comment doesn't make sense.

Point is, SBR & CBR are the specific commands for at least half of the general purpose registers, the others require and & or.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

The point is that there a  NO SBR & CBR instructions , SBR is just a ORI with the bit(s) you want to set and  CBR do a ANDI with the complement of the mask given !

Depending of what you want to do sometimes BST will do what you want if you preload T with 1 if you want to set and 0 for clr, and that is on all 256 (8*32) bits.

With regard to the instructionbs in question, has the AVR instruction set changed since the first databook?

Yes none of the chips in the first databook 1996 was made, and some instructions (4 I think) was added.(I remember it had a AVR1300 a avr 1200 with 128 byte eeprom (and no avr1200))

I'm not sure if the MUL instructions was in the 1997 databook.

For instance, I usually use a lot of flags in my assembly codes.

I start with the bits of r25 then r24, r23... (sometimes, I use the bits of I/O registers if not needed)

```; Bxxxxxxx for SBRC, SBRS
; Fxxxxxxx for SBR , CBR

;.def R1flags  = r25            ; general flags 1

#define B1doJob7 r25,7          ; 1 = do job 7
#define F1doJob7 r25,0x80       ;

#define B1doJob6 r25,6          ; 1 = do job 6
#define F1doJob6 r25,0x40       ;

#define B1doJob5 r25,5          ; 1 = do job 5
#define F1doJob5 r25,0x20       ;

#define B1doJob4 r25,4          ; 1 = do job 4
#define F1doJob4 r25,0x10       ;

#define B1doJob3 r25,3          ; 1 = do job 3
#define F1doJob3 r25,0x08       ;

#define B1doJob2 r25,2          ; 1 = do job 2
#define F1doJob2 r25,0x04       ;

#define B1doJob1 r25,1          ; 1 = do job 2
#define F1doJob1 r25,0x02       ;

#define B1doJob0 r25,0          ; 1 = do job 1
#define F1doJob0 r25,0x01       ;

;==================

; example

....
SBRS  B1doJob2
RJMP  Skip

Job2:
CBR   B1doJob2
...
...

Skip:
....
....
```

Last Edited: Sat. Nov 16, 2019 - 12:50 AM

SBR is just a ORI with the bit(s) you want to set and  CBR do a ANDI

That's worth mentioning...in either case those are specific commands to set general purpose register bits (and they all work ONLY on the 32 general purpose registers), so for OP to say there are no such commands is baloney

I saw that you have SBR and CBR, but you don't have a specific command to set a bit in a general purpose register.

Maybe the real question is what does op mean by  "specific command" ..maybe he mean meant command controlling a single specific bit

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sat. Nov 16, 2019 - 01:06 AM

The problem with AVR bit commands is that the specific bit has to be known at compile time, (no instruction that do something like set the bit r16 point at)

In the past I have used this type of code where 3 bits make this bit mask. (input r16 output r17)

0    00000001

1    00000010

2    00000100

3    00001000

4    00010000

5    00100000

6    01000000

7    10000000

ldi r17,1
sbrc r16,1
ldi r17,4
sbrc r16,0