EmbeddedRelated.com
Forums
Memfault Beyond the Launch

The incfsz command

Started by Jason Hsu May 16, 2008
The loop is always executed the number of times equal to tha maximum
value of Spot1. ie if Spot1 is an 8 bit value the loop executes 256
times, if a 16 bit value it executes 65536 times. The break down is as
follows:-

increment file skip if zero

inc - means increment the file Spot1 before continuing to decode the
rest of the instruction
incf - means the 'file' which is Spot1, so 1 is added to the current
value of Spot1
sz - means skip the next instruction if the value of Spot1 is zero
the final f means that after incrementing the result is stored back to
Spot1as opposed to the W register.

Since Spot1 starts at 0 and is incremented before the first test is
performed the loop always executes until Spot 1 increments past its
maximum value and rollsover back to 0 again.

Al
Jason Hsu wrote:

>Page 11 of the Elmer 160 course (lesson 5) shows an example of a
>counter. The code:
>
> clrf Spot1
>loop
> incfsz Spot1, F
> goto loop
>
>The clrf command sets all bits of register Spot1 to 0.
>The incfsz command increments register Spot1. If F='0', the result of
>this operation is placed in the W register. If F='1', the result of
>this operation is placed back in register Spot1.
>
>Exactly what controls whether the goto loop command is executed?
>Under what circumstances do we stay in the loop, and under what
>circumstances do we skip the "goto loop" command and move on to the
>rest of the program?
>
>
>
The syntax of the incfsz instruction is:

incfsz _register_,destination

Destination can either be 1 or 0. If 0 the result of the increment is
placed in
W and if 1 the result is placed back in _register_. Note that neither
_register_ nor destination are variables but constants, decided and
hardcoded
into the instruction at compile time.

Appart from incrementing and putting the result back in W or
_register_, the
instruction also sets or clers the z(ero) flag. If the result of the
increment
equals 0 (0xff + 1 == 0x00), the z(ero) flag is set. Otherwise it is
cleared.

When all is done, the next instruction to execute is skipped
(actually replaced
wit a nop) if the z(ero) flag is set.

So in other words...

result=_register_;
result=result+1; //remember that 0xff + 1 == 0x00
if (destination==0){
W=result;
} else {
_register_=result;
}

if (result==0){
z=1;
} else {
z=0;
}

if (z=1) {
replace next instruction placed in the instruction fetch que wit nop
meaning next instruction will be skipped
If next instruction is a goto, the goto will be skipped and no jump
will be done. If in a loop, the loop is exited
}

This means that when incfsz is used in a loop where _register_ is the
loop
counter, destination must always be 1 since otherwise the _register_
is never
changed and the loop is run forever.

/Ruben
RJJournal
--- In p..., "Jason Hsu" wrote:
>
> Page 11 of the Elmer 160 course (lesson 5) shows an example of a
> counter. The code:
>
> clrf Spot1
> loop
> incfsz Spot1, F
> goto loop
>
> The clrf command sets all bits of register Spot1 to 0.
> The incfsz command increments register Spot1. If F='0', the result
of
> this operation is placed in the W register. If F='1', the result of
> this operation is placed back in register Spot1.
>
> Exactly what controls whether the goto loop command is executed?
> Under what circumstances do we stay in the loop, and under what
> circumstances do we skip the "goto loop" command and move on to the
> rest of the program?
>

Hi Jason,

I feel your pain and confusion, I have been there.
I trust you will take my comments in the positive spirit that
they are offered. In your original post, you were trying
to understand the "Pic_swr.asm" Assembly language
program. What you were looking at was the ascii text file
that Bert wrote and then submitted to his "Assembler
Program" to convert the Instruction Set mnemonics to a
hex file for loading into the PIC16C71.

So far, you still have not got it.

When defined in the .ASM file (or in the .INC include file)
the ascii letter f or the uppercase F is used as a
"Designator" only. To use F as a destination DESIGNATOR, it is
mandatory that F be equated to the numeric value of ONE,
meaning 0x01 in hex, 00000001 in binary.

F is not a bit.
F is not a register.
F does not change.
F is a "Designator" to the Assembler to interpret it as 1.
F is always 1, never 0 (zero)
F is always 1, for the entire program. That's it.

In your example code snippet:

clrf Spot1
loop
incfsz Spot1, F
goto loop

The third line of code is the instruction "incfsz Spot1, F"
The "instruction" has 3 elements;
element(1) "incfsz" is the mnemonic name for the instruction
that increments a RAM memory location and skips the
next inline instruction if the RAM memory location
value goes to zero.
element(2) "Spot1" is the "name" that you gave the RAM memory
location that you want the instruction to operate on.
element(3) ", F" is the DESTINATION for the results of the
instruction.
In this snippet, the Assembler interprets the third line as:
Increment the value in RAM memory location Spot1, put the result
back into the RAM memory location Spot1, IF the result is ZERO,
then skip the next inline instruction. IF the result is non-zero,
then execute the next [goto loop] instruction. That's all, That's it.

My commebts below are surrounded by ((( and )))

--- In p..., "Jason Hsu" wrote:
> I think I get it now. (The explanations at
http://users.tpg.com.au/users/talking/explaining_instruction_set.html
> were more useful to me than the ones in the datasheet.)
>
> In the statement "incfsz Spot1, F", F=0 if and only if all the bits
in
> register Spot1 are also equal to 0.((( NOT TRUE )))
If any bit in register Spot1 is
> 1, then F='1'.
(((bits in Spot1 have no effect on "F", it is ALWAYS = 1)))
>
> Given the code and the included file that specifies F=1:
> clrf Spot1
> loop
> incfsz Spot1, F
> goto loop
>
> Spot1 is set by the clrf command to "0000000".
(((Spot1 is an 8 bit binary value)))
(((More correctly, RAM location Spot1 is CLEARED to "00000000".)))

(((The following explanation is not correct)))

> Iteration 1: We enter the increment command with F='1', so that
means
> Spot1 is incremented (becomes "0000001") and the next command is
> executed. Because the resulting value in Spot1 is nonzero, F
remains
> equal to 1.
> Iteration 2: F='1' still, so that means Spot1 is incremented
(becomes
> "0000001") and the next command is executed. Because the resulting
> value in Spot1 is nonzero, F remains equal to '1'.
> Later Iteration: We enter a later iteration with Spot1="1111111" and
> F='1', so that means Spot1 is incremented (becomes "0000000") and
the
> next command is executed. But because the resulting value in Spot1
> has all zeros, F is now changed to '0'.
> Final Iteration: We enter the final iteration with Spot1="0000000"
and
> F='0'. Because F='0', the resulting value of "0000001" goes into
the
> W register instead of Spot1. Also, because F='0', the next
> instruction is skipped, and we move out of the loop.
>

(((program execution steps)))
(((Iteration 1: The 8 bit value in Spot1 is brought to the ALU and
incremented. Because of the F destination DESIGNATOR, the
incremented value "00000001" is put back to location Spot1, since
the result of the increment is non-zero, the next instruction, "goto
loop" is executed.)))
(((Iteration 2: The 8 bit value in Spot1 is brought to the ALU and
incremented. Because of the F destination DESIGNATOR, the
incremented value "00000010" is put back to location Spot1, since
the result of the increment is non-zero, the next instruction, "goto
loop" is executed.)))
(((Iteration 3: The 8 bit value in Spot1 is brought to the ALU and
incremented. Because of the F destination DESIGNATOR, the
incremented value "00000011" is put back to location Spot1, since
the result of the increment is non-zero, the next instruction, "goto
loop" is executed.)))
(((this looping process continues [binary counting])))
(((Iteration 255: The 8 bit value in Spot1 is brought to the ALU and
incremented. Because of the F destination DESIGNATOR, the
incremented value "11111111" is put back to location Spot1, since
the result of the increment is non-zero, the next instruction, "goto
loop" is executed.)))
(((Iteration 256: The 8 bit value in Spot1 is brought to the ALU and
incremented. Because of the F destination DESIGNATOR, the
incremented value "00000000" is put back to location Spot1, since
the result of the increment IS NOW ZERO, the next instruction, "goto
loop" is SKIPPED.)))
(((execution now continues at the instruction FOLLOWING the "goto
loop" instruction.)))
(((NOTE: Spot1 now contains"00000000", W the working register was not
involved and F never "changed" in value.)))

((( I hope you will find this helpful and that you will continue to
study and practice the art and science of PIC programming.)))

((( Best regards, Eric)))

This applies to all instructions that can take the f or w suffix (you have to previously define f=1, w=0 of course)

If you don't add the suffix to an instruction that is able to take this extra parameter it defaults to f ( 1 ).

Cheers, Guy

----- Original Message -----
From: Jason Hsu
To: p...
Sent: Friday, May 16, 2008 10:18 PM
Subject: [piclist] Re: The incfsz command
OK, now I understand why w=0 and f=1. If you use w as the second
argument for an -sz command, the result is stored in the W directory.
If you use f as the second argument for an -sz command, the result is
stored in the file register. Now things are making sense.

Memfault Beyond the Launch