You are on page 1of 63

EE260 Lecture 12

Introduction to Assembly Language:


Prepare to Assemble.

Introduction to Assembly
The motivation behind Assembly!
The scheme of Assembly!
The Assembly environment!
Sample codes

EE260 Lecture 12: Introduction to Assembly Language Programming

Motivation for Assembly Language

Why Learn Assembler?


directly analyze for bugs!
understanding why a program executes
differently than designed!
higher level language doesnt support all the
hardware features!
time-critical routines

EE260 Lecture 12: Introduction to Assembly Language Programming

Why Learn Assembler?


code is short and easy!
code executes as fast as possible!
assembler is easy to learn :-}!

and FUN!

code can take full advantage of the hardware


features.!
allows understanding of the compilation process
of a program (e.g. calling conventions)
EE260 Lecture 12: Introduction to Assembly Language Programming

Why Learn Assembler?


learning it for one processor makes it easy to
learn another dialect.!
by learning it, you simultaneously learn the
hardware!
it is simple: it always only does what you ask it
to.! and FUN!
its optimized for speed and space
EE260 Lecture 12: Introduction to Assembly Language Programming

Why Learn Assembler?


assembly is naked (nothing hidden)!
allows for exact algorithm analysis!
a core dump can be used with assembly to debug a
problem.!
timing for a certain function can be obtained by
counting the operations required to fulfill it

EE260 Lecture 12: Introduction to Assembly Language Programming

Why Learn Assembler?


enables newb programmers to become Experts.!
Assembly language programmers earn more $$$!
Writing assembly language is fun.!

and FUN!

Allows programmers to look like cyber geeks.

EE260 Lecture 12: Introduction to Assembly Language Programming

Applications for Assembly


Device Drivers!
Low-level embedded systems!
Real-time systems!
Speed-critical systems!
Space-critical systems!
Allows for parallel processes on a non-parallel
machine
EE260 Lecture 12: Introduction to Assembly Language Programming

C can be close to assembly


Both can:

access all the functions/ registers of the


ATMega328!
have a decidedly smaller footprint than Arduino
code.!
have time-sensitive functionality

EE260 Lecture 12: Introduction to Assembly Language Programming

Important Differences
In Assembly

working with the program counter and the stack.!


no predefined data types!
working directly with addresses or pointers

EE260 Lecture 12: Introduction to Assembly Language Programming

The Assembly Language Scheme

The Build Process


file.c
file.cpp

Preprocessor

file.i
file.ii

Compiler

file.s

Assembler

file.o

header1.h
headern.h

file.cmd
file1.o,...
file1.lib,...

Linker

file.map
file.out

Binary
Convertor

file.exe, file.srec, file.bin, file.hex, file.elf, file.coff

EE260 Lecture 12: Introduction to Assembly Language Programming

The Hardware
central processing unit!
(arithmetic logic unit)!
diverse storage units!
ports that control the peripherals!
GPIO!
timers!
other devices
EE260 Lecture 12: Introduction to Assembly Language Programming

How the CPU works


Reads an instruction (instruction fetch) from program
storage!
Loads data from data storage into necessary registers!
Executes the command!

EE260 Lecture 12: Introduction to Assembly Language Programming

Example Codes
Code (bin)

Code
(hex)

Put CPU to sleep

1001.0101.1000.1000

9588

Add register R1 to register R0

0000.1100.000.0001

0c01

Subtract register R1 from register R0

0001.1000.0000.0001

1801

Write constant 170 to register R16

1110.1010.0000.1010

ea0a

Multiply register R3 with register R2 and write the


result to registers R1 (MSB) and R0 (LSB)

1001.1100.0011.0010

9c32

CPU Operation

EE260 Lecture 12: Introduction to Assembly Language Programming

Executing: OCO1
Add register R0 to R1

0c01
ALU

Register
R0

Register
R1

ALU
+
ADD

EE260 Lecture 12: Introduction to Assembly Language Programming

ALU
+
ADD
Register
R0
write result to R0

Classes of Operations
Arithmetic and logic instructions!
Branch instructions!
Bit and bit-test instructions!
Data transfer instructions!
MCU control instructions
mnemonics
EE260 Lecture 12: Introduction to Assembly Language Programming

Operands
Data that the operation operates on!
Data must be put into specific registers in order to
operated on (executed)!
Arduino operations use at most 2 operands.

EE260 Lecture 12: Introduction to Assembly Language Programming

Possible Input/Output
Command Schemes
Input

Output

one 8-bit operand

one 8-bit result

two 8-bit operands

one 8-bit result

two 8-bit operands

one 16-bit result

one 16-bit operand

one 16-bit result

EE260 Lecture 12: Introduction to Assembly Language Programming

How is data included?


For a load command LDI R,C
we have the code:
15

14

13

12

11

10

c7

c6

c5

c4

r3

r2

r1

r0

c3

c2

c1

c0

Crazy-HuH?
EE260 Lecture 12: Introduction to Assembly Language Programming

Example Subroutine
InitializeOutput:
ldi r18, LED_PIN_MASK
sts PORTB_DDR_ADDR, r18
sts PORB_DATA_ADDR, r18
!

ret

EE260 Lecture 12: Introduction to Assembly Language Programming

Assembly Language
Mnemonics for the machine instructions!
Register names R0R31!
Directives: create data, specify addresses!
Symbols: names for values or addresses!
Syntax specifies addressing modes!
Numerical values (e.g., 23)!
Comments
EE260 Lecture 12: Introduction to Assembly Language Programming

Assembly Code Forms


Every line of code should be one of the following

1.[label:] directive [operands][Comment]


2.[label:] instruction [operands][Comment]
3.Comment
4.Empty line

EE260 Lecture 12: Introduction to Assembly Language Programming

Assembly Code
Lines should be limited to 120 characters!
Labels!
An alphanumeric string ending with at colon!
targets for jump and branch instructions!
Variable names in Program memory and RAM!

Comments!
; [text], or # [text]

EE260 Lecture 12: Introduction to Assembly Language Programming

Assembly Code Example


label:

.equ var1, 100

;set var1 to 100

.equ var2, 200

;set var2 to 200

Directive
test:

nop

;infinite loop

rjmp test

Instructions

; pure comment line


; another comment line

EE260 Lecture 12: Introduction to Assembly Language Programming

Operand Forms
Rd

Destination (& source) register R0-R31 or R16-R31

Rr

Source register R0-R31

Bit in the Register file or I/O Register (3-bit constant)

Bit in the Status Register (3-bit)

X,Y,Z Indirect Address Register (X=R27:R26, Y=R29:R28, Z=R31:R32)


K

Constant data

Constant Address

I/O location address

Displacement for direct addressing (6-bit)

PC

Program Counter

EE260 Lecture 12: Introduction to Assembly Language Programming

Operands
Labels; value of the location counter at the place they appear!
Variables defined by the .set directive!
Constants defined by the .equ directive!
Integer constants!
Decimal: 10, 255
Hex: 0x0a, or $0a!
Binary: 0b00001010!
Program counter (PC)

EE260 Lecture 12: Introduction to Assembly Language Programming

Operators
Symb

Name

Returns

Priority

Logical Not

1 if the expression is 0, 0 otherwise

14

Bitwise Not

all bits inverted

14

unary minus

the arithmetic negation of expression

14

multiplication

the product of the two expressions

13

division

the integer quotient (1st exp)/(2nd exp)

13

addition

the sum of the two expressions

12

subtraction

the difference (1st exp) (2nd exp)

12

<<

shift left

the (1st exp) shifted to the left by the (2nd exp)

11

>>

shift right

the (1st exp) shifted to the right by the (2nd exp)

11

<

less than

1 if the (1st exp) is less than the (2nd exp), 0 else

10

EE260 Lecture 12: Introduction to Assembly Language Programming

Operators
Name

Symb

Returns

Priority

<=

less or equal

1 only if the (1st exp) is less or equal to the (2nd exp)

10

>

greater than

1 if the (1st exp) is greater than the (2nd exp), 0 else

10

greater or equal

1 only if the (1st exp) is greater or equal to the (2nd exp)

10

equal

1 if the (1st exp) is equal to the (2nd exp), 0 else

not equal

1 if the (1st exp) is not equal to the (2nd exp), 0 else

&

bitwise AND

the bitwise AND of two expressions

bitwise XOR

the bitwise XOR of two expressions

bitwise OR

the bitwise OR of two expressions

&&

logical AND

true only if both operands are true

||

logical OR

true if either operand is true

>=
==
!=

EE260 Lecture 12: Introduction to Assembly Language Programming

Directives
not translated into op-codes!
they are used to:!
adjust the location of the program in memory !
define macros !
initialize memory!
...
EE260 Lecture 12: Introduction to Assembly Language Programming

Directives
.byte

Reserve byte to a variable

.comm

declares a common symbol

.data

specifies the Data section of a program.

.ifdef

tells the assembler to include the following code if the


condition is satisfied.

.else

tells the assembler to include the following code if the if


condition is false.

.include

include supporting files

#include

include supporting files

.file

start of a new logical file

EE260 Lecture 12: Introduction to Assembly Language Programming

Directives
.text

assemble what follows onto the end of the text subsection

.global

defines or acknowledges a global variable or subroutine,


often used with a variable specified by .comm

.extern

treats all undefined symbols as external

.space

allocates space (for an array)

.equ

define constants for use in a program

.set

define (local) variables used in a program

EE260 Lecture 12: Introduction to Assembly Language Programming

Directives
.abort
.align
.ascii
.asciz
.balign[
wl]
.byte
.comm
.data
.def
.dim
.double
.eject
.else
.end

.elseif
.endef
.endfunc
.endif
.endm
.endr
.equ
.equiv
.err
.even
.exitm
.extern
.fail
.file
.fill

.float
.func
.global
.hword
.ident
.if
.include
.incbin
.int
.irp
.irpc
.lcomm
.lflags
.line
.ln

.list
.long
.macro
.mri
.nolist
.octa
.org
.p2align
[wl]
.print
.psize
.purgem
.quad
.rept
.sbttl

EE260 Lecture 12: Introduction to Assembly Language Programming

.scl
.section
.set
.short
.single
.size
.sleb128
.skip
.space
.stabd
.stabn
.stabs
.string
.struct
.tag

.text
.title
.type
.uleb128
.val
.vtable_
entry
.word

The Assembly Environment

Setting up the Arduino


Assembly
The Arduino IDE doesnt directly allow assembly!
A number of approaches exist to do assembly
with the Arduino IDE:
1. Modify the IDE!
2. Inline Assembly!
3. Use AVR Studio instead of the Arduino IDE
EE260 Lecture 12: Introduction to Assembly Language Programming

AVR Studio/Toolchain

Slick integrated environment (Windows)!


Directly incorporates Assembly!
Requires knowledge of the bootloading process!
For power users.
EE260 Lecture 12: Introduction to Assembly Language Programming

Inline Assembly
Allows for all the assembly commands and
structures.!
Requires a lot of extra stuff in the code to support
the program that is not a part of the program!
more difficult to read/debug

EE260 Lecture 12: Introduction to Assembly Language Programming

Inline Assembly Example Line


asm("in %0, %1 \n\t : "=r" (value) : "I" (_SFR_IO_ADDR(PORTD)) );

asm() indicates to the IDE that assembly is used!


The assembler instruction is defined as a single string
constant: "in %0, %1 \n\t!
The list of output operands follow, separated by commas.
"=r" (value)
Next, a comma separated list of input operands.
"I" (_SFR_IO_ADDR(PORTD))
EE260 Lecture 12: Introduction to Assembly Language Programming

Inline Assembly
Recommended by the Text!
Useful for incorporating a
single command!
Not practical for code of any
length.

EE260 Lecture 12: Introduction to Assembly Language Programming

Modifying the IDE


The Arduino IDE is OPEN SOURCE!!
This means that anyone can modify it for their
purposes.!
The source code is freely available.!
Requires a process that needs to be done
whenever you wish to upgrade to the latest
version.
EE260 Lecture 12: Introduction to Assembly Language Programming

Modifying the IDE


The Arduino IDE actually uses the gcc process
which includes assembly language.!
The IDE needs to be modified to accept .s files.!
The gcc standard uses .s files (not .S) for
assembly files.

EE260 Lecture 12: Introduction to Assembly Language Programming

Modifying the Arduino IDE


http://rwf.co/dokuwiki/doku.php?id=smallcpus
(for MacOs, but applies to others)

1. Get the source code for the Arduino IDE.


https://github.com/arduino/Arduino!
2. Extract to obtain the folder Arduino-master.!
3. Open the Sketch.java file in a text editor
Arduino-master/app/src/processing/app/Sketch.java
EE260 Lecture 12: Introduction to Assembly Language Programming

Modifying the Arduino IDE


4. Insert the .s capability
Search for: sc.isExtension("c")
...
// 3. then loop over the code[] and save each .java file
!

for (SketchCode sc : code) {


if (sc.isExtension("c") || sc.isExtension("cpp") || sc.isExtension("h")) {
// no pre-processing services necessary for java files
...

insert

if (sc.isExtension("c") || sc.isExtension("cpp") || sc.isExtension("h") || sc.isExtension("s")) {

EE260 Lecture 12: Introduction to Assembly Language Programming

Modifying the Arduino IDE


4. Insert the .s capability
Search for: String[] getExtensions()
...
/**
* Returns a String[] array of proper extensions.
*/
public String[] getExtensions() {
return new String[] { "ino", "pde", "c", "cpp", "h" };
}
...

insert

return new String[] { "ino", "pde", "c", "cpp", h, s };

5. Save Sketch.java
EE260 Lecture 12: Introduction to Assembly Language Programming

Modifying the Arduino IDE


6. Open Complier.java in a text editor.
Arduino-master/app/src/processing/app/debug/Compiler.java

7. Search for: compileFiles(!


8. In the command findFilesInFolder(), replace the
capital S with lowercase s.!
9. Repeat this search and do the replace (3 more times).!
10. Save the Compiler.java file.
EE260 Lecture 12: Introduction to Assembly Language Programming

Modifying the Arduino IDE


11. Make sure you have a recent version of the Java
platform on your system
http://www.oracle.com/technetwork/java/javase
/downloads/index-jsp-138363.html

EE260 Lecture 12: Introduction to Assembly Language Programming

Modifying the Arduino IDE


12.Make sure you have a Java command-line tool installed
on your system. Apache ANT is recommended. This is
available for Mac, Windows, and Linux.
Windows Help:
https://ant.apache.org/manual/install.html
Mac: For OS 10.9 and above, this needs to be installed!
using Homebrew. In a terminal window:
ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

then!
brew install ant
EE260 Lecture 12: Introduction to Assembly Language Programming

Modifying the Arduino IDE


13. In your command window, move to wherever you have the
directory!
Arduino-master/build
14. Build the Arduino IDE using: ant build
(which should end with BUILD SUCCESSFUL)!
15. Package the Arduino IDE using: ant dist
It will ask you to enter a version number, and give a
suggestion, e.g. [0105]. I recommend you tack on asm, for
example, enter: 1.0.5.asm
(it may take about 6 minutes and end with BUILD SUCCESSFUL)
EE260 Lecture 12: Introduction to Assembly Language Programming

Modifying the Arduino IDE


16. The Arduino IDE can be found in the zip file created.!
17. Unzip the file and install the application in some
reasonable place on your computer.!
18.The IDE just created should function exactly as the one
you download off the arduino.cc siteexcept it can
handle .s files!

EE260 Lecture 12: Introduction to Assembly Language Programming

Sample Codes

Coding using the New IDE


Including the assembly still requires a .ino file.!
It will also require a .s file.!
It may require a .h file.!
The .s and .h files will need to be created with
the same name as the .ino file, in a text editor.!
All the files need to be in the same directory!
Opening the .ino file opens the other(s).
EE260 Lecture 12: Introduction to Assembly Language Programming

Test Code 1
asmtest.ino
#include "asmtest.h"
!

asmtest.h
/* Global register variables.*/
#ifdef __ASSEMBLER__

void setup()
{
asminit(0);
}

void loop()
{
led(0);
delay(1000);
led(1);
delay(1000);
}

/* C-only stuff */

/* Assembler-only stuff */
!

#else /* !ASSEMBLER */

#include <stdint.h>
!

extern "C" uint8_t led(uint8_t);


extern "C" uint8_t asminit(uint8_t);
!

#endif /* ASSEMBLER */
EE260 Lecture 12: Introduction to Assembly Language Programming

Test Code 1
asmtest.s

#include "avr/io.h"
#include "asmtest.h"

.global asminit ; Define the function asminit()
.global led ; The assembly function must be declared as global
asminit:
sbi 4,5 ; 4 = DDRB (0x24 - 0x20). Bit 5 = pin 13
ret
!

led:
cpi r24, 0x00 ; Parameter passed by caller in r24
breq turnoff
sbi 5, 5 ; 5 = PORTB (0x25 - 0x20). Bit 5 = pin 13
ret
turnoff:
cbi 5, 5 ; 5 = PORTB (0x25 - 0x20). Bit 5 = pin 13
ret
EE260 Lecture 12: Introduction to Assembly Language Programming

Test Code 2
asmtest2.ino

EE260 Lecture 12: Introduction to Assembly Language Programming

asmtest2.h

Test Code 2

asmtest2.s

#include "avr/io.h"
#define yl r28
#define yh r29
#define delay 1000 // const long delay = 1000ms;
!

.global setup
.global loop
setup:
sbi _SFR_IO_ADDR(DDRB), DDB5 ; Bit 5 = pin 13
ret
loop:
push yl
push yh
call millis ; call millis(): 4-byte return value in r25...r22
// Use Y as a pointer to fetch the next time to switch the LED
ldi yl, lo8(nextSwitchAfterMillis)
ldi yh, hi8(nextSwitchAfterMillis)
ld r18, y+
ld r19, y+
EE260 Lecture 12: Introduction to Assembly Language Programming

Test Code 2

asmtest2.s

ld r20, y+
ld r21, y+
ld r17, y // ledStatus comes immediately after lastMillis, so we can use y
// Compare nextSwitchAfterMillis with value returned by millis()
sub r18, r22
sbc r19, r23
sbc r20, r24
sbc r21, r25
brcc tooEarly ; carry is set if r18...r21(nextSwitchAfterMillis) < r22...r25(millis())
// Toggle LED state: 0 -> 1, 1 -> 0
inc r17
andi r17, 1
// Store ledStatus for next time. y still points at its memory location
st y, r17
// set LED state
brne turnoff
cbi _SFR_IO_ADDR(PORTB), PORTB5; Bit 5 = pin 13
rjmp ledSwitched
EE260 Lecture 12: Introduction to Assembly Language Programming

Test Code 2

asmtest2.s

turnoff:
sbi _SFR_IO_ADDR(PORTB), PORTB5; Bit 5 = pin 13
!

ledSwitched:
// Add long delay; to result of call to millis()
ldi r17, lo8(delay)
add r22, r17
ldi r17, hi8(delay)
adc r23, r17
ldi r17, hlo8(delay)
adc r24, r17
ldi r17, hhi8(delay)
adc r25, r17
// Store this as the next point in time when we need to toggle the LED
st -y, r25
st -y, r24
st -y, r23
st -y, r22

EE260 Lecture 12: Introduction to Assembly Language Programming

Test Code 2
tooEarly:
pop yh
pop yl
ret
!

.data
!

nextSwitchAfterMillis:
.long 0
!

ledStatus:
.byte 0

EE260 Lecture 12: Introduction to Assembly Language Programming

asmtest2.s

Test Code 3
speedArduino.ino
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
digitalWrite(13, HIGH);
digitalWrite(13, LOW);
}

EE260 Lecture 12: Introduction to Assembly Language Programming

speedC.ino
void setup()
{
DDRB |= (1<<5);
}
void loop()
{
while(1)
{
PORTB |= 0x20;
PORTB &= ~(0x20);
}
}

Test Code 3
speedASM.ino

speedASM.s
.global setup
.global loop
setup:
sbi 0x04, 5 ; DDRB 5 = pin 13
ret
loop:
sbi 0x03, 5 ; write PINB5 -> 1 (toggle)
sbi 0x03, 5 ; (toggle again)
rjmp loop ; used an rjmp, not ret

EE260 Lecture 12: Introduction to Assembly Language Programming

Program Results
Binary Size!
(bytes)

Speed!
(kHz)

Arduino

874

121

472

2,667

Assembly

472

4,002

EE260 Lecture 12: Introduction to Assembly Language Programming

Program Results
Arduino

121kHz

2.66MHz

Assembly

4.00MHz

EE260 Lecture 12: Introduction to Assembly Language Programming

You might also like