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.

'Variable' Pushing/Popping

Status
Not open for further replies.

Thorpydo

New Member
Hey,
I just have some questions about the solutions to problems I've been having. I'm mostly just looking for an explantion; so I actually understand what's going on.

I'm using the control directive 'variable'. I'm first just wondering if I can modify the byte being used with the regular assembly language as well as with the variable directive.

The next thing I'm trying to figure out (which kind of goes with the last question) is if and how the pop and push work with a byte defined by the variable directive. I looked in the MCU Section 8 about interrupts. The example for pushing the W and STATUS register shows that they first copy W to a temporary register, then swap status nibbles and place in W register, and lastly, save STATUS to a temporary register in bank0.

I don't understand the purpose of swaping nibbles or why, once they save the STATUS register to another temporary register, it suddenly is saved when an interrupt comes around.

Popping looks like it works pretty much the same way.

Thanks
 
After a little more reading.... Would I be correct to assume that only the Z STATUS and similar registers are cleared when an interrupt occurs. General purpose registers remain unchanged and that is why the STATUS register would be saved to a general purpose register. The nibbles are swapped and stored to a new register as oppose to just moving them, because swapping them doesnt affect the Z and similiar regsiters?
 
Thorpydo said:
After a little more reading.... Would I be correct to assume that only the Z STATUS and similar registers are cleared when an interrupt occurs. General purpose registers remain unchanged and that is why the STATUS register would be saved to a general purpose register. The nibbles are swapped and stored to a new register as oppose to just moving them, because swapping them doesnt affect the Z and similiar regsiters?

The STATUS register isn't altered by an interrupt, BUT you need to save and restore it because your interrupt routine is quite likely to modify it, many instructions affect the STATUS bits. Obviously if the STATUS register is altered during an interrupt it will cause chaos in the main program. As with any interrupt routine, it must not alter anything that can affect the main program - except where it's intended to!.
 
Thorpydo said:
Hey,
I'm using the control directive 'variable'. I'm first just wondering if I can modify the byte being used with the regular assembly language as well as with the variable directive.
I'm not sure what you mean by this, maybe you can rephrase the question?
You do know that the variable directive makes a preprocessor variable at compile time, not a runtime variable?

Thorpydo said:
The next thing I'm trying to figure out (which kind of goes with the last question) is if and how the pop and push work with a byte defined by the variable directive. I looked in the MCU Section 8 about interrupts. The example for pushing the W and STATUS register shows that they first copy W to a temporary register, then swap status nibbles and place in W register, and lastly, save STATUS to a temporary register in bank0.

I don't understand the purpose of swaping nibbles or why, once they save the STATUS register to another temporary register, it suddenly is saved when an interrupt comes around.

Popping looks like it works pretty much the same way.

Like Nigel exaplained, an interrupt can occur at any moment when the pic is running the main program. This means it can be doing instruction X - then get an interrupt, and then return to instruction X + 1.
Now, the interrupt routine is likely to change STATUS and W, because almost all instructions do so, if the interrupt routine wouldn't save STATUS and W then instruction X+1 could find itself with messed up values in STATUS and W - for sure this would go wrong...

As the interrupt routine can happen at any moment you don't know what memory bank you're in when you enter the interrupt routine, therefore W is copied to a memory position wich should be available in all banks (check the datasheet, the lower 16 bytes of most pic's are mirrored in all banks)

Then they use swapf to copy the contents of STATUS to W, they use swapf because it is the only instruction that does not modify the STATUS flags. once this is done they just save the STATUS copy in W to memory.

Context restoring works the same way, but in reverse...
 
Hey, and thank you for the help!

"You do know that the variable directive makes a preprocessor variable at compile time, not a runtime variable?"

- I didn't know that, and still don't know exactly what that means. I don't know what a preprocessor variable or runtime variable are. I was using the variable directive just like I would a byte only because it was simlier to write and understand. Is that the wrong use for it?
 
Thorpydo said:
Hey, and thank you for the help!

"You do know that the variable directive makes a preprocessor variable at compile time, not a runtime variable?"

- I didn't know that, and still don't know exactly what that means. I don't know what a preprocessor variable or runtime variable are. I was using the variable directive just like I would a byte only because it was simlier to write and understand. Is that the wrong use for it?

Yes it is - it's an 'assembler directive', when you assemble the program it inserts the 'numeric value' of the variable into the program.

For an example, you write a program that can be used in two different versions - say it's a game, either a two player or four player game. Most of the source code will be identical, but there will be parts (obviously) where you will need either 2 or 4 inserting in the program. By using a variable directive you can assign the value 2 or 4 to a variable, which you insert at the required point.

Then to assembler either version of the game you simply alter the variable to 2 or 4 as you require, and when you assemble it makes the correct version.

A common use is assembling for different processors, you set a variable to the particular processor you're using, then the source checks the variable and assembles the correct code - something like this:

Code:
Processor = 16F84
If processor = 16F84 Then
  use this bit
If Processor <> 16F84 Then
  use this bit

But really the assembler variables are nothing to do with your program, just variables within the assembling process - generally you don't need them, and you are doomed to failure if you try to use them to write programs.

Try assembling a program, then disassembling it (you can use WinPicProg for this) - then compare it to what you started with. The latest beta version of WinPicProg even inserts variable names (which it obviously has to make up), so you can easily spot variables (registers) and constants (numbers)
 
Thorpydo said:
"You do know that the variable directive makes a preprocessor variable at compile time, not a runtime variable?"

- I didn't know that, and still don't know exactly what that means. I don't know what a preprocessor variable or runtime variable are.

compile time - Code or variables that get used/executed at compile time - commonly used for conditional assembly - none of these actually get tranferred to the pic!
run time - The actual code or variables that do get transferred to the pic, this is the actual program the pic runs...

To give a example of compile time code, say you have a project wich may need to run on a pic16f84 or a 16f627. and assume the program is 100% identical for both, except for 1 function, you could then use:


Code:
variable device=1      ;1 = 16f84, 2 = 16f627

if device = 1 then

;Code for 16f84 here

endif

if device = 2 then

;code for 16f627 here

endif
A compile time variable named 'device' will be created, holding value 1. The if statement below will only compile the code for the desired processor. As you can see, 'device' is only used when compiling, it is not a variable wich can and may be used by the pic program itself...

hope this makes some sense :?
 
Status
Not open for further replies.

Latest threads

Back
Top