How exactly do you create a loop with Assembly language

Thread Starter

specs365

Joined Mar 14, 2019
29
Hi everyone, I understand this is a very basic question, but I'm still very new to assembly. I would just basically like to understand what the the following means:
=> The F and A after the decfsz command.
=> how do I know how many time the loop will execute (Probably something to do with the above question).

Here is my code. I'm just trying to flash some LEDs with a period of 1s

P.S. I'm not really sure if the decfsz command is used correctly.
Code:
; -----------------------------------------------------------------------------
; EMK310
; Example code 1.1
; Basic assembler program structure
; Lecturer: Prof T Hanekom
; Date of last revision: February 2016
;------------------------------------------------------------------------------
; SIMULATION, i.e. use SIMULATOR
; Check list:     1*. Simulation (no physical hardware) vs Programmer (stand alone)
;                       vs Debugger (ICD functionality)
;------------------------------------------------------------------------------
; Functioning: We first load 0Fh into the working register (WREG) and then from
; the WREG into PORTA (address 0F80h). We then clear WREG by loading 0F00h into
; and it and then into PORTA. Does it work? Why?
;
; Notes:
; 1. Two different but equivalent ways of specifying hex numbers in code
;      80h (for any number starting with a number) = 0x80 (equivalent)
;      0F80h (if the number starts with a letter) = 0xf80 (equivalent)
;      For WATCH window: use 0xF80
;
; 2. Directives
;       Help Contents > Language Tools > MPASMX Toolchain > MPASM Assembler > Directives
;       Read through the information in this help file to familiarise yourself
;       with the nature and use of directives. Identify the directives in the
;       code below and look up their typical use in the help files.
; -----------------------------------------------------------------------------
  
        title         "Our first Assembler program"
        list          P=PIC18F45K22 ; processor type - include in your test & exam
                                  ; code so we can see you selected the correct
                                  ; device
        #include    "p18f45K22.inc
; -------------
; PROGRAM START
; -------------
;
        org         0h     ; startup address = 0000h

start     movlw            0xFF         ; move 11111111b to W register
        movwf         PORTA        ; move W to port A
        movlw         0x00         ; move 00000000b to W register
        movwf         PORTA        ; move W to port A
        BRA        delay
  
delay        equ  0x0F
  
    again    nop        ;1 Instruction cycle each
        nop
        nop
        nop
  
        decfsz    delay, F, A
  
        BRA    start  
        BRA    again        ;2 Intruction cycles
  
        end
Mod edit: code tags
 
Last edited by a moderator:

Thread Starter

specs365

Joined Mar 14, 2019
29
Code:
        title         "Our first Assembler program"
        list          P=PIC18F45K22 ; processor type - include in your test & exam
                                  ; code so we can see you selected the correct
                                  ; device
        #include    "p18f45K22.inc"
  
  
  
  

;
; -------------
; PROGRAM START
; -------------
;
        org         0h     ; startup address = 0000h
  
  

  

  

start     movlw            0xFF         ; move 11111111b to W register
            movwf         PORTA        ; move W to port A
            movlw         0x00         ; move 00000000b to W register
            movwf         PORTA        ; move W to port A
            BRA        delay
  
delay        equ  0x0F
  
again        nop        ;1 Instruction cycle each
             nop
             nop
             nop
  
             decfsz    delay, F, A
  
             BRA    start  
             BRA    again        ;2 Intruction cycles
  
             end
 

Ian Rogers

Joined Dec 12, 2012
774
The loop will be 255.. "decfsz" is analysed after the event so 0 become 255 once this counts down F = 0 then the loop breaks. However... I just noticed that F is never initialized so the first loop could be anything.
 

JohnInTX

Joined Jun 26, 2012
4,072
There is another bug. Line 30 says
BRA delay

But 'delay' here is intended to be an address in RAM, not a label in the code. It would assemble as:
BRA 000Fh
which is not what you want.

FWIW, in this case, you would get a lucky error 12 from MPASM because the target address of that BRA is not word aligned i.e. an even number. But if 'delay' were an even number, the assembler would happily use that and you'd have some debugging to do.

Have fun learning!
 

jpanhalt

Joined Jan 18, 2008
9,405
Code:
start
            movlw         0xFF         ; move 11111111b to W register
            movwf         PORTA        ; move W to port A
            movlw         0x00         ; move 00000000b to W register
            movwf         PORTA        ; move W to port A
            BRA           again        ; NOTE

delay        equ  ox0F               ;0x2F

again        nop        ;1 Instruction cycle each
             nop
             nop
             nop

             decfsz    delay,F

             BRA    start
             BRA    again        ;2 Intruction cycles

             end
Had to make a few changes to run on a 16F1829. That code does compile and simulates, but doesn't do what you may thing it does. Line 9 had to be changed as that simply specifies a RAM location. 0x0F is not valid on the 16F. As Ian points out, delay is not initialized, so it can start with any value, go to zero, and wrap around.

I suggest listing your "equates" earlier in the code and not inline.

The "bra delay" just sits at the spot and does noting, because there are no instructions at that RAM location. That is why it was changed to "bra again."

PS: Sorry for all the edits, I accidentally hit the Enter key and posted the code before adding any comments.
@JohnInTX
Sorry to duplicate you. I started simulation, then writing long before you posted, then got distracted trying to fix the error in posting the code with no comment.
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,072
@jpanhalt No worries!

For @specs365
Your code does not initialize PORTA. On any PIC, you have to do some setup on the ports to make them work. Section 10.0 I/O ports in the datasheet details what you need to do there. You need to set the direction of the pins (input or output) using the TRIS register and also make the pins digital (some are analog after a RESET) using ANSELA. Init the ports once before entering your main loop.

The ,F and ,A modifiers to decfsz and others are covered in 25.1 Standard Instruction Set.
,F means that the result of the operation - in this case decrementing the register called 'delay' - is put back into the register which is what you want. The alternative is ,W which puts the result of the decrement in WREG. Not what you want here but look at movf for a good example of using ,W.
,A means that the register is in the Access RAM. Access RAM is always accessable so for now it's a good, easy place to put things. If you look at Figure 5-5 in the datasheet, you'll see that most of the RAM in this chip is in banks. If the 'delay' register was in one of those, you would have to specifically set the bank select register (BSR) to point at that bank before using that instruction. I'm sure your instructor will cover all of that as you go along.

http://ww1.microchip.com/downloads/en/DeviceDoc/40001412G.pdf
 

BobaMosfet

Joined Jul 1, 2009
1,106
Hi everyone, I understand this is a very basic question, but I'm still very new to assembly. I would just basically like to understand what the the following means:
=> The F and A after the decfsz command.
=> how do I know how many time the loop will execute (Probably something to do with the above question).

Here is my code. I'm just trying to flash some LEDs with a period of 1s

P.S. I'm not really sure if the decfsz command is used correctly.
Code:
; -----------------------------------------------------------------------------
; EMK310
; Example code 1.1
; Basic assembler program structure
; Lecturer: Prof T Hanekom
; Date of last revision: February 2016
;------------------------------------------------------------------------------
; SIMULATION, i.e. use SIMULATOR
; Check list:     1*. Simulation (no physical hardware) vs Programmer (stand alone)
;                       vs Debugger (ICD functionality)
;------------------------------------------------------------------------------
; Functioning: We first load 0Fh into the working register (WREG) and then from
; the WREG into PORTA (address 0F80h). We then clear WREG by loading 0F00h into
; and it and then into PORTA. Does it work? Why?
;
; Notes:
; 1. Two different but equivalent ways of specifying hex numbers in code
;      80h (for any number starting with a number) = 0x80 (equivalent)
;      0F80h (if the number starts with a letter) = 0xf80 (equivalent)
;      For WATCH window: use 0xF80
;
; 2. Directives
;       Help Contents > Language Tools > MPASMX Toolchain > MPASM Assembler > Directives
;       Read through the information in this help file to familiarise yourself
;       with the nature and use of directives. Identify the directives in the
;       code below and look up their typical use in the help files.
; -----------------------------------------------------------------------------

        title         "Our first Assembler program"
        list          P=PIC18F45K22 ; processor type - include in your test & exam
                                  ; code so we can see you selected the correct
                                  ; device
        #include    "p18f45K22.inc
; -------------
; PROGRAM START
; -------------
;
        org         0h     ; startup address = 0000h

start     movlw            0xFF         ; move 11111111b to W register
        movwf         PORTA        ; move W to port A
        movlw         0x00         ; move 00000000b to W register
        movwf         PORTA        ; move W to port A
        BRA        delay

delay        equ  0x0F

    again    nop        ;1 Instruction cycle each
        nop
        nop
        nop

        decfsz    delay, F, A

        BRA    start
        BRA    again        ;2 Intruction cycles

        end
Mod edit: code tags
Since you're interested in assembly language, let's help you grasp the jargon. An assembly language instruction is called a 'mnemonic' (you can pronounce that 'knee-monic' or 'new-monic' as you prefer- but probably somewhere in between those two is what you're striving for). Each assembly instruction is spelled in a way to describe what it is. 'bra' = branch. 'decfsz' = decrement the file, skip if zero.

You need to look at a reference like this to wrap your head around what you're doing. Assembly language doesn't do much per instruction, but it executes so quickly it can do more than anything else.

http://users.tpg.com.au/users/talking/explaining_instruction_set.html

A loop works in assembly just like any other. You compare some value (usually to zero because that's the only value you know that doesn't have to be declared), and then either keep executing, or branch elsewhere.

Just bear in mind that in assembly language, you have to do everything- nothing is done for you. You are responsible for everything (setup, execution, tear down, managing memory, your registers, stack, frames, etc). But that also gives you the most power.
 
Last edited:

MaxHeadRoom

Joined Jul 18, 2013
20,678
Hi everyone, I understand this is a very basic question, but I'm still very new to assembly. I would just basically like to understand what the the following means:
=> The F and A after the decfsz command.
The instructions section in the manual will give you the significance of each for decfsz, if needing the value of F and A, it is listed in the .INC file for the PIC.
Max.
 
Top