You are on page 1of 14

Control structures

Hot to translate high level control structures to assembler

If a then b else c endif


Note that if a then b endif is a special case of the above. In PIC assembler this takes the general form: Assume a is a bit flag in a register 1. btfss a ; if a then skip next instr 1. goto l1 ; if a false goto l1 2. ;code to do b 3. goto l2 4. l1 5. ;code to do c 6. l2

while a do b endwhile

On a PIC you do the following 1. l1 ; start label 2. btfss a ; test condition a 3. goto l2 ; if a is false we go to end 4. ; code for action b 5. goto l1 ; try again 6. l2 ; end while label

Repeat loop
High Level Code Repeat A Until b;
1. 2. 3. 4. 5. 6.

Assembler Startlabel ; code for A btfss b ; test b goto exitlabel goto startlabel exitlabel

For Loops
For

i:=20 downto 1 do A Movlw 20 ; set i:=20 Movwf regi Startlabel ; code for A DECFSZ regi,1 ; decrement skip zero goto startlabel ; repeat if >0

Upward for loops


For i:=1 to 10 do A Movlw 10 ; set count:=10 Movwf count clrf regi ; initialise i to 0 Startlabel incf regi,1 ; increment I, thus =1 first time ; code for A DECFSZ count,1 ; decrement skip zero goto startlabel ; repeat if >0

Switch statement
This

is explained in the last lecture on state machines.

Call subroutine

A simple parameterless subroutine can be done as follows Foo()

Call foo Foo ; code for foo return

Subroutines with parameters

In assembler one normally writes routines to pass parameters in registers, If you are calling routines written in High level language from an assembler program on a big CISC processor like a Pentium, then you have to follow the high level language calling convention. On RISC machines registers are used for parameters even on big processors

Passing Parameters
Suppose

we want to call a simple function foo which takes 2 byte integer parameters. Suppose that it just adds the two bytes for now. We want the effect of calling foo(1,2)

Register passing of params


Suppose

the C definition of foo was foo(char a, char b){ return a+b;} We may choose to pass parameter a in the W register and assign another register ( say 7f ) to pass B in.

Example call code


; foo(1,2); MOVLW 02 ; w:=2 MOVWF 07Fh; reg7f:=w MOVLW 0x01 ; w:=1 CALL foo

Called code
; char foo(char a, char b) ; { return (char)(a+b);} foo ADDWF 07fh,W RETURN On entry a is in W and b is in reg7f, we return the result in W

Nested calls
If foo were to call another routine then the w and 7f registers would be corrupted, thus you need to save the parameters in other registers at the start of foo foo MOVWF 24h ; save w in reg 24 MOVF 07Fh,W MOVWF 25h ; save reg7f in reg25 ; rest of code for foo

You might also like