Lecture 12
Lecture 12
Lecture 12
Introduction to Assembly
The motivation behind Assembly!
The scheme of Assembly!
The Assembly environment!
Sample codes
and FUN!
and FUN!
Important Differences
In Assembly
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
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
Example Codes
Code (bin)
Code
(hex)
1001.0101.1000.1000
9588
0000.1100.000.0001
0c01
0001.1000.0000.0001
1801
1110.1010.0000.1010
ea0a
1001.1100.0011.0010
9c32
CPU Operation
Executing: OCO1
Add register R0 to R1
0c01
ALU
Register
R0
Register
R1
ALU
+
ADD
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.
Possible Input/Output
Command Schemes
Input
Output
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
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
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]
Directive
test:
nop
;infinite loop
rjmp test
Instructions
Operand Forms
Rd
Rr
Constant data
Constant Address
PC
Program Counter
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)
Operators
Symb
Name
Returns
Priority
Logical Not
14
Bitwise Not
14
unary minus
14
multiplication
13
division
13
addition
12
subtraction
12
<<
shift left
11
>>
shift right
11
<
less than
10
Operators
Name
Symb
Returns
Priority
<=
less or equal
10
>
greater than
10
greater or equal
10
equal
not equal
&
bitwise AND
bitwise XOR
bitwise OR
&&
logical AND
||
logical OR
>=
==
!=
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
.comm
.data
.ifdef
.else
.include
#include
.file
Directives
.text
.global
.extern
.space
.equ
.set
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
.scl
.section
.set
.short
.single
.size
.sleb128
.skip
.space
.stabd
.stabn
.stabs
.string
.struct
.tag
.text
.title
.type
.uleb128
.val
.vtable_
entry
.word
AVR Studio/Toolchain
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
Inline Assembly
Recommended by the Text!
Useful for incorporating a
single command!
Not practical for code of any
length.
insert
insert
5. Save Sketch.java
EE260 Lecture 12: Introduction to Assembly Language Programming
then!
brew
install
ant
EE260 Lecture 12: Introduction to Assembly Language Programming
Sample Codes
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>
!
#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
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
asmtest2.s
Test Code 3
speedArduino.ino
void
setup()
{
pinMode(13,
OUTPUT);
}
void
loop()
{
digitalWrite(13,
HIGH);
digitalWrite(13,
LOW);
}
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
Program Results
Binary Size!
(bytes)
Speed!
(kHz)
Arduino
874
121
472
2,667
Assembly
472
4,002
Program Results
Arduino
121kHz
2.66MHz
Assembly
4.00MHz