lecture_5 introduction to assembly language programminglec5

Upload: usman-ullah-asif

Post on 30-May-2018

220 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    1/25

    Lecture 5

    Introduction to Assembly

    Language Programming

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    2/25

    Assembly vs. High Level Language

    Assembly is a low-level language. It is different fromother high-level languages.

    High level languages are abstract. A single high levelinstruction is translated into several machine language

    instructions. Over time the level of abstraction of high-level language

    is increasing.

    Assembly is harder to program than high levellanguages.

    Assembly Language program can be 20 times fasterthan high level program.

    Assembly gives direct access to hardware features.

    Faster development time for high level programs.

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    3/25

    Assembly vs. High Level Language

    Unsigned int outdata=0;

    For (outdata=0;outdata

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    4/25

    Simplest program possible

    main: ;this is the label main

    rjmp main ;Relative Jump to main

    Main is used a label.

    This label replaces an address in FLASH.

    rjmp main is places at exactly this address.

    Upon execution CPU will jump to main.

    Jump will be repeated over and over, resulting inan infinite loop.

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    5/25

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    6/25

    Flashing LED program

    We want to make an LED flash. LED will show active low behaviour After reset, all Data bits are set to zero, so the LED

    should be ON when the program is executed

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    7/25

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    8/25

    Flashing LED program

    Basically we want to switch LED on and off in a loop.

    We use cbi (clear bit in I/O) and sbi (set bit in I/O).

    We will see LED being on all the time. I cycle for LED off then 1 cycle(0.00000025) later it is on again. Rjmp takes 2 cycles (0.0000005).

    We naturally need delay.

    .org 0x0000

    rjmp main

    main:

    ldi r16, 0xFF

    out DDRB, r16

    loop:sbi PortB, 3

    cbi PortB, 3

    rjmp loop

    ; the next instruction has to be written to address 0x0000

    ; the reset vector: jump to "main"

    ;

    ; this is the label "main"

    ; load register 16 with 0xFF (all bits are 1)

    ; write the value in r16 (0xFF) to Data Direction Register B

    ;; switch off the LED

    ; switch it on

    ; jump to loop

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    9/25

    Flashing LED program

    For 0.5s delay at 4MHz equals 2,000,000 cycles.

    An 8-bit register can only hold values 0 to 255 soit wont be enough. Registers can be used inpairs so we can work on values from 0 to 65535.

    clr r24

    clr r25

    delay_loop:

    adiw r24, 1

    brne delay_loop

    ; clear register 24

    ; clear register 25

    ; the loop label

    ; "add immediate to word": r24:r25 are incremented

    ; if no overflow ("branch if not equal"), go back to "delay_loop"

    4(2adiw+2brne)*0xFFFF(looping) +3(overflow 2adiw+1brne) + 2(clr) = 262145cycles. This is still not enough:

    2,000,000/262,145 ~ 7.63.

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    10/25

    Flashing LED program We will create a loop around the inner loop.

    We change clr to ldi so that we can use different start value than 0.

    The outer loop will down-count from 8 to 0.

    The overall loop needs: 262,145 (inner loop) + 1 (dec) + 2 (brne) = 262148 *8 = 2097184 cycles plus the initial ldi = 2097185 minus one since last brnedidnt result in a branch. This is 97184 cycles too long. We will fine-tune with

    initial value in r24:r25. Subtract : 97184 / 8 =12148 cycles per inner loop. Inner loop takes 4 cycles.

    So 12148/4=3037 less iterations. This is initial value in r24:r25.

    ldi r16, 8

    outer_loop:

    ldi r24, 0

    ldi r25, 0delay_loop:

    adiw r24, 1

    brne delay_loop

    dec r16

    brne outer_loop

    ; load r16 with 8

    ; outer loop label

    ;

    ; clear register 24

    ; clear register 25; the loop label

    ; "add immediate to word": r24:r25 are incremented

    ; if no overflow ("branch if not equal"), go back to "delay_loop"

    ;

    ; decrement r16

    ; and loop if outer loop not finished

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    11/25

    .org 0x0000

    rjmp main

    main:

    ldi r16, low(RAMEND)

    out SPL, r16

    ldi r16, high(RAMEND)

    out SPH, r16

    ldi r16, 0xFF

    out DDRB, r16

    loop:

    sbi PortB, 3

    rcall delay_05cbi PortB, 3

    rcall delay_05

    rjmp loop

    delay_05:

    ldi r16, 8

    outer_loop:

    ldi r24, low(3037)

    ldi r25, high(3037)delay_loop:

    adiw r24, 1

    brne delay_loop

    dec r16

    brne outer_loop

    ret

    ; the next instruction has to be written to address 0x0000

    ; the reset vector: jump to "main"

    ;

    ;

    ; set up the stack

    ;

    ;

    ;

    ;

    ; load register 16 with 0xFF (all bits are 1)

    ; write the value in r16 (0xFF) to Data Direction Register B

    ;

    ; switch off the LED

    ; wait for half a second; switch it on

    ; wait for half a second

    ; jump to loop

    ;

    ; the subroutine:

    ; load r16 with 8

    ; outer loop label

    ;

    ; load registers r24:r25 with 3037, our new init value

    ;; the loop label

    ; "add immediate to word": r24:r25 are incremented

    ; if no overflow ("branch if not equal"), go back to "delay_loop"

    ;

    ; decrement r16

    ; and loop if outer loop not finished

    ; return from subroutine

    Also add .include m16def.inc or any relevant file such as m8def.inc

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    12/25

    The Stack

    Stack is like a notepad to remind you where you just left in

    case you are visiting several locations.

    Stack pointer tells you where that stack is.

    When a subroutine is called, it leaves the place in flash whereit was just working and saves the return address on the stack.

    The stack needs a stack pointer (SP) and space in SRAM (the

    stack pointer must point above the first SRAM address).

    When a return address is stored, the SP is post-decremented.

    i.e. the Stack is growing towards smallerSRAM addresses. Biggest stack possible is initialized to RAMEND till first SRAM

    location.

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    13/25

    The Stack

    .include m16def.inc

    .def temp = r16

    .org 0x00

    ldi temp, low(RAMEND)

    out SPL,temp

    ldi temp, high(RAMEND)

    out SPH, temp

    rcall subrtn_1

    .org 0x100

    subrtn_1:

    rcall subrtn_2

    ret

    .org 0x140

    subrtn_2:

    ret

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    14/25

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    15/25

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    16/25

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    17/25

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    18/25

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    19/25

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    20/25

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    21/25

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    22/25

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    23/25

    Push/Pop

    The stack can also be used to pass arguments tosubroutines using push and pop

    push r16

    push r17

    rcall set_TCNT1

    set_TCNT1:

    pop r17

    pop r16

    out TCNT1H, r17

    out TCNT1L, r16

    ret

    ; push 16-but argument r16:r17

    ;

    ; and call the subroutine;

    ; our subroutine writes its 16-bit argument to the Timer 1 counter

    ; register. It pops the argument from the stack

    ; (reversed order!)

    ; and uses it

    ;

    ; now it returns.

    The stack can also be used to pass arguments tosubroutines using push and pop.

    Balance Push and Pop. Missing a pop or too many popsabove can cause error on Subroutine return.

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    24/25

    Stack Initialization forSubroutines

  • 8/9/2019 Lecture_5 Introduction to Assembly Language ProgrammingLec5

    25/25

    Subroutines

    RAMEND is defined in the micros include file you get with

    AVRStudio and equal to the last available internal SRAM address.

    A subroutine begins with a label which is the subroutine's name.

    .include "m16def.inc"

    ldi r16, low(RAMEND)

    out SPL, r16

    ldi r16, high(RAMEND)

    out SPH, r16

    main:

    rcall out_PortA

    rjmp main

    out_portA:

    out PortA, r16

    ret

    Rcall: This instruction jumps

    to a relative address and is

    2 bytes long and needs 3

    cycles for execution. The

    disadvantage is that the

    subroutine has to belocated at +/- 2k words. Call

    can be used for absolute

    addressing (4bytes,

    4cycles). The 8k AVRs only

    need rjmp and rcall.