Help with ASM, and compare and rol.

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm missing something fundamental here, looking for some advice.

 

I have a byte where I need to check the last bit for 1 or 0 and choose a path, then shift that bit off. Thinking a register pair would work with a rol but currently my data is in r16.

 

Here was my attempt.

 

mov r19, r16 //move data from r16 to r19

andi r19, 0x80  ; and the last bit , result goes in r19 ?
 cpi     r19, 0     ;     //check if its a 0 or 1.
 breq sb_send0%=; //path for 0
 rjmp sb_send1%= ; //path for 1

 

later on do a

 lsr r16     

 

The above does not seem to work, is there faster/better way to do this operation?

 

 

 

 

 

 

 

 

This topic has a solution.
Last Edited: Tue. Feb 23, 2021 - 02:41 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

you can do 

sbrs r16, 0

rjmp was lo

rjmp was hi

 

-------------------------

to get rid of the bit (shifting) just  do:

lsr r16

 

if 2 bytes (shifting, working 16 bits) do

lsr r19

ror r16

---------

after the single byte lsr shift or compound 2-byte ror shift, you could test

 

brcc  was_low

rjmp was_hi

 

 

 

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

Last Edited: Mon. Feb 22, 2021 - 08:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Will always be 8bit in this case.

 

sbrs r16, 7    would skip if value was 0x80 right? And I'd want to shift left, in this case.

visual exmaple...

Starting with 100100

test the 7th bit go to lable:  sb_send1%=

shift it off 001000 remains

 

sbrs r16, 7            
breq sb_send0%=        
rjmp sb_send1%=        

 

.

.

.

.

lsl r16

 

 

Last Edited: Mon. Feb 22, 2021 - 08:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

FYI, ANDI sets (or clears) the Z bit in SREG, depending on the result of the ANDI operation, So, you do not have to test the result against zero. It is already there in SREG. Then you can use either BREQ or BRNE to branch based on the value of Z. That is one of several ways of doing it with fewer instructions.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sbrs r16, 7    would skip if value was 0x80 right? 

You live a dangerous life!

 

yes 0x80, and 0x81, and 0xE7, 0xA9,  etc ...many skip...don't overlook that (when it detects 0x80, machine will dispense $100 winnings

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

Last Edited: Mon. Feb 22, 2021 - 11:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will add to #4

 

You have to go thru the instructions ad get a clear picture of witch flags in SREG the instructions change and the name for the branches that correlate.

(if you aren't used to signed 8 bit I think that the S flag will be last to master.)

 

  

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

About #5

OP wants to to check highest bit so he and the rest off, so just check for high bit is fine with SBRS R19,7

 

But for the code in #1 you don't need r19 for anything this code will solve the same problem:

or r16,r16 ; don't change r16, but update flags

brmi L1    ; jump if bit 7 set

;code for cleared here

.

.

.

lsr r16

 

 

edit error in code 

add: the code above don't change the Carry flag.

 

An other way is code that does.

you want to check if bit 7 is set or not, that also means that if you subi 0x80 from r16 the carry flag now hold the info you want if the value was below 0x80 you had to borrow and Carry would be set, so if Carry cleared the bit was set. Now you don't want to sub $80 from r16 so you do a cpi  with 0x80 so the flags get's updated but not r16 :

 

cpi r16,0x80

brcc ; bit 7 was set

; here if bit 7 was cleared

 

 

 

 

lsr r16   

 

 

 

 

 

 

Last Edited: Mon. Feb 22, 2021 - 11:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would probably do:

 

   lsl r16
   brcs sb_send1%   // bit was one.
   // bit was zero code.

 

Which merges the shift and the setting of flags based on the old register contents into one instruction (the MSB is shifted into the carry flag.  (but it might not be available if you wanted to look at it again.)

But honestly, I don't see why your original code isn't working, even if it's longer than needed.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OP want r16 to shift right ! not left

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I also need the test before the shift.

 

This worked  best for me

or r16,r16 ; don't change r16, but update flags

brmi L1    ; jump if bit 7 set

;code for cleared here

.

.

.

lsr r16

if it was broken code it worked nicely :)

 

or r16,r16        
brmi make_a_1%= 
rjmp make_a_0%=   

 

to be precise.

 

Last Edited: Tue. Feb 23, 2021 - 02:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good you solved it, and bit 7 is always easy to check for.

But if you want to learn ASM then perhaps also take a look BST, and then branch on the T flag, it's especially help full if you need to remember the result for a while.