Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Trying to understand some simple code

Status
Not open for further replies.

Andy1845c

Active Member
Am am trying to get a firm grip on programming in Assembly. I can sort of modify some code, but I am trying to understand it well so I can write from scratch.

I have been running the code below in the MPLAB sim, and I can't figure out where we suddenly get 255 to put into Delay1 and count down from. Don't we have to put a number in W, then move it to where ever we want it? It just seems to pop in there out of thin air.

I also am fuzzy on the "f" after delay1 and delay2. As silly of a question as this probably is, can someone point me toward some info on it?

Code:
#include <p16F690.inc>
    __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
    cblock 0x20
Delay1                   ; Define two file registers for the
Delay2                   ; delay loop
     endc
 
     org 0
Start:
     bsf       STATUS,RP0          ; select Register Page 1
     bcf       TRISC,0             ; make IO Pin B.0 an output
     bcf       STATUS,RP0          ; back to Register Page 0
MainLoop:
     bsf       PORTC,0             ; turn on LED C0
OndelayLoop:
     decfsz    Delay1,f            ; Waste time.  
     goto      OndelayLoop         ; The Inner loop takes 3 instructions per loop * 256 loopss = 768 instructions
     decfsz    Delay2,f            ; The outer loop takes and additional 3 instructions per lap * 256 loops
     goto      OndelayLoop         ; (768+3) * 256 = 197376 instructions / 1M instructions per second = 0.197 sec.
                                   ; call it a two-tenths of a second.
 
     bcf       PORTC,0             ; Turn off LED C0
OffDelayLoop:
     decfsz    Delay1,f            ; same delay as above
     goto      OffDelayLoop
     decfsz    Delay2,f
     goto      OffDelayLoop
     goto      MainLoop            ; Do it again...
     end
 
Hi Andy,
The timer rolls over from hex 0 to hex FF (which is 255 decimal.) does that make sense for you?

The 'f' after the register name, means do the operation on the register. The other option is 'w' after the register name, and the operation would be carried out in the accumulator (W register.)

I hope this makes sense for you, but if it doesn't I will try to be more clear.

Regards

Am am trying to get a firm grip on programming in Assembly. I can sort of modify some code, but I am trying to understand it well so I can write from scratch.

I have been running the code below in the MPLAB sim, and I can't figure out where we suddenly get 255 to put into Delay1 and count down from. Don't we have to put a number in W, then move it to where ever we want it? It just seems to pop in there out of thin air.

I also am fuzzy on the "f" after delay1 and delay2. As silly of a question as this probably is, can someone point me toward some info on it?

Code:
#include <p16F690.inc>
    __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
    cblock 0x20
Delay1                   ; Define two file registers for the
Delay2                   ; delay loop
     endc
 
     org 0
Start:
     bsf       STATUS,RP0          ; select Register Page 1
     bcf       TRISC,0             ; make IO Pin B.0 an output
     bcf       STATUS,RP0          ; back to Register Page 0
MainLoop:
     bsf       PORTC,0             ; turn on LED C0
OndelayLoop:
     decfsz    Delay1,f            ; Waste time.  
     goto      OndelayLoop         ; The Inner loop takes 3 instructions per loop * 256 loopss = 768 instructions
     decfsz    Delay2,f            ; The outer loop takes and additional 3 instructions per lap * 256 loops
     goto      OndelayLoop         ; (768+3) * 256 = 197376 instructions / 1M instructions per second = 0.197 sec.
                                   ; call it a two-tenths of a second.
 
     bcf       PORTC,0             ; Turn off LED C0
OffDelayLoop:
     decfsz    Delay1,f            ; same delay as above
     goto      OffDelayLoop
     decfsz    Delay2,f
     goto      OffDelayLoop
     goto      MainLoop            ; Do it again...
     end
 
Hi Andy,
The timer rolls over from hex 0 to hex FF (which is 255 decimal.) does that make sense for you?

Ahhhh...... that makes sense..... so pretty much we go to subtract 1 from an empty space and it just rolls right to 255 or hex FF.... THANK YOU as simple as that I I would have never figured it out......:eek:

Hi Andy,
The 'f' after the register name, means do the operation on the register. The other option is 'w' after the register name, and the operation would be carried out in the accumulator (W register.)

So, in the case of the code I posted, " decfsz Delay1,f " mean to simply subtract 1 from the register named "delay1" and not bother the W register?

Is this opposed to moving the value that is in "delay1" into W, subtracting there and then putting the new value back in "delay1"?

I'm still a bit fuzzy on this, but i think its getting clearer.....
 
Ahhhh...... that makes sense..... so pretty much we go to subtract 1 from an empty space and it just rolls right to 255 or hex FF.... THANK YOU as simple as that I I would have never figured it out......:eek:

I know what you mean, most of the time I make everything too complicated.:p Got to remember to kiss!

So, in the case of the code I posted, " decfsz Delay1,f " mean to simply subtract 1 from the register named "delay1" and not bother the W register?

Is this opposed to moving the value that is in "delay1" into W, subtracting there and then putting the new value back in "delay1"?
If I remember, it is opposed to moving the value in "delay1" into W, subtracting there, and leaving it there.

I'm still a bit fuzzy on this, but i think its getting clearer.....
I'm still a bit fuzzy on this, too! OK, I'd best go look this one up... back in a minute...

OK, that seems correct. I found it in the document "17381-movfw-pic_instruction_reference-1.pdf," which I'm having trouble finding on MicroChip's site... I probably re-named it or something....

If you look on page 4 of https://www.electro-tech-online.com/custompdfs/2008/11/31029a.pdf that will tell all.
 
Last edited:
And the natural question to follow is:

If W has a previous value x, does the operation "decfsz delay,f" change the original x value in W?
 
And the natural question to follow is:

If W has a previous value x, does the operation "decfsz delay,f" change the original x value in W?

As I see it, the answer is "yes".

To decrease the file delay, the operation must be performed in the w register. Hence, any data previously existing would be replaced, the action performed and the new value replaced in the delay file.

Should the previous data in w need to be preserved, it should be temporarily stored in a shadow file for later use.

IMO.
 
And the natural question to follow is:

If W has a previous value x, does the operation "decfsz delay,f" change the original x value in W?

hi,
No, the value in W is preserved.

The [delay] register is decremented, not W.
 
And the natural question to follow is:

If W has a previous value x, does the operation "decfsz delay,f" change the original x value in W?

According to MicroChip's docs, if I'm reading correctly, the file register 'delay' is decremented directly. They refer to f or W as the 'destination.'

This instruction is documented on page 22, of the above doc 31029a. the first document I referred to was "MPASM User’s Guide with MPLINK and MPLIB Quick Reference" From page 3:
Most instructions operate on a file register, f, and the
working register, W (accumulator). The result can be directed either to the file
register or the W register or to both in the case of some instructions.

From page 22 of the document I linked to:
The contents of register 'f' are decremented. If 'd' is 0 the result is placed
in the W register. If 'd' is 1 the result is placed back in register 'f'.
If the result is 0, then the next instruction (fetched during the current
instruction execution) is discarded and a NOP is executed instead, making
this a 2 cycle instruction.

which makes it sound like the opp is performed on the file directly. (?) Although, what AllVol said
the operation must be performed in the w register.
made me go look things up.

The diagram on page 87 of the Mid-range reference manual makes things very clear: the opp is performed by the ALU and the result placed in the destination. If that destination is f, then W is not used at all.

Thanks to both Andy and Eblc for the questions! :)
 
Thanks for the help. I think things are finally sinking in as far as how PICs work. I just printed out the link you posted. It looks like a good read through for a beginner like myself.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top