how to remember (visualize?) the flow of a DECFSZ instruction

In experimenting with pics, (and probably other micros) one of the often used instructions is DECFSZ, often followed by a goto (or even pair of them) to get the program to branch as desired.

I always end up getting confused, and have to explicitly work out the logic and put it in the comments in detail to try to not get it backwards and branch the wrong way. And even with that, I get maybe 20% of them wrong anyway and only find it in debuging.

BLEAH !!!

There has to be a mnemonic or way of looking at it which helps keep it straight. Anyone have any suggestions.

P.S. any help for the same issue with BTFSC and BTFSS

Reply to
m
Loading thread data ...

You need to know that the S prior to the last character means "skip the next instruction". Maybe if you say it out loud: DECFSZ = Decrement F skip the next instruction if the result is 0 BTFSC = Bit test F skip the next instruction if the bit is clear (0) BTFSS = Bit test F skip the next instruction if the bit is set (1)

It can help if you use self-indicating names for the registers indicated by F, and for the labels. For example:

DECFSZ ItemsToPack would be better than DECFSZ I GOTO COUNTITEM would be better than GOTO C GOTO ALLCOUNTED would be better than GOTO A

Ed

Reply to
ehsjr

Write some macros?

John

Reply to
John Larkin

Answer his question? Ever thing maybe his assembler doesn't support macro's?

Reply to
Jeff Johnson

Very simple. It skips over the next instruction if the resulting computation resulted in a zero.

if (x - 1 == 0) skip over next instruction.

(of course it stores the result in x)

So,

DECFSZ x, f GOTO A GOTO B

so, if x = 1, then we goto B, else A.

You can think of it as, if the register contains 1 we skip 1 instruction. (so, if x == 1 we skip over one instruction(putting us at GOTO B. Just remember that it stores the result in x)

Reply to
Jeff Johnson

I can't tell from here; most assemblers do have some macro or at least aliasing capability. I wrote a preprocessor (and a postprocessor) for my assembler to do stuff that its limited macro capability can't do, like generate floating-point constants and implement some of the stranger 68K 64-bit instructions.

I think the PIC was derived from the PDP-8, so it has those weird conditional skip things. They are harder to think about than conditional branches.

John

Reply to
John Larkin

RTFM the instruction set? Easy.

DECFSZ - decrement f, skip if zero BTFSC - bit test f, skip if clear BTFSS - bit test f, skip if set

The mnenonics are simple in any case, providing you accept that a 'file' is an addressed entity of 8 bits (aka byte) ;)

Default PIC assembler does macros. The one that comes in free MPLAB wot Jan dislikes ;)

Conditionals skip the following instruction when condition met, so they look 'backwards'?

Grant.

Reply to
Grant

Some people seems to have missed the point, which isn't (AFAICT) to ask what those instructions literally mean, but how to write code which uses them but remains comprehensible.

The problem is that a "skip" instruction tells the CPU /not/ to do something (a negation), and it's quite command that the instruction to be skipped is itself a goto which skips over a block of code, meaning that you can end up with so many negations that you lose track of which way round you have it. Bonus pain if the bit being tested is active low.

E.g.: if (port1.pin1) { dothis(); dothat(); }

Becomes: BTFS? port1, pin1 GOTO dont_doit CALL dothis CALL dothat dont_doit:

Should that BTFS? be BTFSC or BTFSS? I.e. should you skip over the GOTO instruction which skips over the block if the bit is clear or set?

You can cancel out of one of the negations (the "skip" in the BTFS? instructions) using macros:

if_set macro reg, bit btfsc reg, bit endm

if_clr macro reg, bit btfss reg, bit endm

So you can write:

if_clr port1, pin1 GOTO dont_doit ...

At least those two instructions can then be "read" without confusion.

Reply to
Nobody

MPASM (actually MPASMWIN now) supports the following pseudo-instructions for PIC10/12/16 targets which go a long way towards making PIC code readable:

ADDCF f,d Add Carry to File * ADDDCF f,d Add Digit Carry to File * B k Branch BC k Branch on Carry * BDC k Branch on Digit Carry * BNC k Branch on No Carry * BNDC k Branch on No Digit Carry * BNZ k Branch on No Zero * BZ k Branch on Zero * CLRC Clear Carry CLRDC Clear Digit Carry CLRZ Clear Zero LCALL k Long Call * LGOTO k Long GOTO * MOVFW f Move File to W NEGF f,d Negate File * SETC Set Carry SETDC Set Digit Carry SETZ Set Zero SKPC Skip on Carry SKPDC Skip on Digit Carry SKPNC Skip on No Carry SKPNDC Skip on No Digit Carry SKPNZ Skip on Non Zero SKPZ Skip on Zero SUBCF f,d Subtract Carry from File * SUBDCF f,d Subtract Digit Carry from File * TSTF f Test File

See Reference -> Instruction Sets -> 12-Bit/14-Bit Instruction Width Pseudo-Instructions in the MPASMWIN help file for more details. GPASM is highly MPASM compatible so it should have them too.

All those marked with a '*' generate multiple instructions in the object code so must NOT be used immediately after any Skip instruction, and are not atomic from an interrupt point of view.

For PIC18 targets, they aren't valid but can fairly simply be duplicated by writing macros of the same name.

Also, all bank and page select operatons should be done with the banksel f and pagesel addr directives - really psudeo-instructions that generate the correct 'bit-twiddling' sequence on the appropriate SFR.

If DECFSZ .. GOTO continues to offend you, as it isn't in the list above you will have to write a DJNZ macro.

--
Ian Malcolm.   London, ENGLAND.  (NEWSGROUP REPLY PREFERRED)
ianm[at]the[dash]malcolms[dot]freeserve[dot]co[dot]uk
 Click to see the full signature
Reply to
IanM

Until you start using them to create higher level constructs, like DO or WHILE loops.

Reply to
krw

Great idea. You could use macros for that.

John

Reply to
John Larkin

Yup. At one time I had a full set of PL/I branch/loop constructs for ASM86. I particularly like PL/I's SELECT/WHEN construct. Very powerful.

Reply to
krw

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.