Sei sulla pagina 1di 100

Arithmetic Instructions

Syntax: <instruction>{<cond>}{S} Rd, Rn, N


•ADC add two 32-bit values and carry
Rd = Rn + N + carry
•ADD add two 32-bit values
Rd = Rn + N
•RSB reverse subtract of two 32-bit values
Rd = N − Rn
•RSC reverse subtract with carry of two 32-bit values
Rd = N − Rn − !(carry flag)
• SBC subtract with carry of two 32-bit
values
Rd = Rn − N − !(carry flag)
• SUB subtract two 32-bit values
Rd = Rn − N
ADD R1,R2,R3 ;R1=R2+R3
ADDC R1,R2,R3 ;R1=R2+R3+C
SUB R1,R2,R3 ;R1=R2-R3
SUBC R1,R2,R3 ;R1=R2-R3+C-1
RSB R1,R2,R3 ;R1=R3-R2
RSC R1,R2,R3 ;R1=R3-R2+C-1
AREA Rotate, CODE, READONLY
ENTRY

LDR R0,=0X80000000
MOV R2,#0X00000000

SUBS R4,R0,R2 ;C=1,N=1(B=0)


SBC R5,R4,#01

stop B stop
END
R4:0x80000000
R5:0x7FFFFFFF
AREA Rotate, CODE, READONLY
ENTRY

LDR R0,=0X80000000
MOV R2,#0X0000000F

SUBS R4,R0,R2
SBC R5,R4,#01

stop B stop
END
• R0 0x80000000
• R2 0x0000000F

• R4 0x7FFFFFF1
• R5 0x7FFFFFF0

• CPSR:V=1 C=1
EG
AREA Rotate, CODE, READONLY
ENTRY

LDR R0,=0X80000000
MOV R2,#0X0000000F

SUBS R4,R0,R2
;SBC R5,R4,#01
MOV R5,R0,RRX

stop B stop
END
R0 0x80000000

CPSR V=1 C=1

R5 = 0xC0000000

ELSE
R5=0x40000000
AREA Rotate, CODE, READONLY
ENTRY

LDR R0,=0X80000000
MOV R2,#0X0000000F
MOVS R5,R0,LSL #01
stop B stop
END
CPSR : Z=1 C=1 V=0//DOESNT AFFECT V FLAG
Eg:subtract instruction subtracts a value stored in
register r2 from a value stored
in register r1. The result is stored in register r0.
PRE r0 = 0x00000000
r1 = 0x00000002
r2 = 0x00000001

SUB r0, r1, r2

POST r0 = 0x00000001
This reverse subtract instruction (RSB) subtracts
r1 from the constant value #0, writing the
result to r0. You can use this instruction to
negate numbers.
PRE r0 = 0x00000000
r1 = 0x00000077

RSB r0, r1, #0 ; Rd = 0x0 - r1

POSTr0 = -r1 = 0xffffff89


The SUBS instruseful for decrementing loop
counters.In this example we subtract
the immediate value one from the value one
stored in register r1. The result value zero is
written to register r1. The cpsr is updated with
the ZC flags being set.
PRE cpsr = nzcvqiFt_USER
r1 = 0x00000001
SUBS r1, r1, #1
POSTcpsr = nZCvqiFt_USER
r1 = 0x00000000
Example illustrates the use of
the inline barrel shifter with an arithmetic
instruction. The instruction multiplies the value
stored in register r1 by three.
PRE r0 = 0x00000000
r1 = 0x00000005

ADD r0, r1, r1, LSL #1

POST r0 = 0x0000000f

r1 = 0x00000005
64 bit addition:
r3 r2 (1st operand)
r1 r0 (2nd operand)
------------
r5 r4 (result)
________

ADDS R4, R0,R2


ADC R5,R1,R3
64 bit SUBTRACTION:
r1 r0 (1st operand)
r3 r2 (2nd operand)
------------
r5 r4 (result)
________

SUBS R4,R0,R2
SBC R5,R1,R3
Find absolute

CMP R1,#0
RSBLT R0,R1,#0
done B done
Logical Instructions
Syntax: <instruction>{<cond>}{S} Rd, Rn, N
AND logical bitwise AND of two 32-bit values
Rd = Rn & N
ORR logical bitwise OR of two 32-bit values
Rd = Rn | N
EOR logical exclusive OR of two 32-bit values
Rd = Rn ∧N
BIC logical bit clear (AND NOT)
Rd = Rn & ∼N
This example shows a logical OR operation
between registers r1 and r2. r0 holds the
result.

PRE r0 = 0x00000000
r1 = 0x02040608
r2 = 0x10305070
ORR r0, r1, r2

POSTr0 = 0x12345678
This example shows a more complicated logical instruction
called BIC, which carries out
a logical bit clear.

PRE r1 = 0b1111
r2 = 0b0101

BIC r0, r1, r2

POST r0 = 0b1010

This is equivalent to

Rd = Rn AND NOT(N)
Comparison Instructions
Syntax: <instruction>{<cond>} Rn, N
• CMN compare negated
flags set as a result of Rn + N
• CMP compare
flags set as a result of Rn − N
• TEQ test for equality of two 32-bit values
flags set as a result of Rn ∧ N
• TST test bits of a 32-bit value
flags set as a result of Rn & N
This example shows a CMP comparison instruction. You
can see that both registers, r0 and
r9, are equal before executing the instruction. The value
of the z flag prior to execution is 0
and is represented by a lowercase z. After execution the z
flag changes to 1 or an uppercase
Z. This change indicates equality.

PRE cpsr = nzcvqiFt_USER


r0 = 4
r9 = 4
CMP r0, r9

POST cpsr = nZcvqiFt_USER


Multiply Instructions
Syntax:
MLA{<cond>}{S} Rd, Rm, Rs, Rn
MUL{<cond>}{S} Rd, Rm, Rs

• MLA multiply and accumulate


Rd = (Rm∗Rs) + Rn
• MUL multiply
Rd = Rm∗Rs
LONG MULTIPLY
Syntax: <instruction>{<cond>}{S} RdLo, RdHi, Rm, Rs
• SMLAL signed multiply accumulate long
[RdHi, RdLo] = [RdHi, RdLo] + (Rm ∗Rs)
• SMULL signed multiply long
[RdHi, RdLo] = Rm ∗Rs
• UMLAL unsigned multiply accumulate long
[RdHi, RdLo] = [RdHi, RdLo] + (Rm ∗Rs)
• UMULL unsigned multiply long
[RdHi, RdLo] = Rm ∗Rs
PRE r0 = 0x00000000
r1 = 0x00000002
r2 = 0x00000002

MUL r0, r1, r2 ; r0 = r1*r2

POSTr0 = 0x00000004
r1 = 0x00000002

r2 = 0x00000002
PRE r0 = 0x00000000
r1 = 0x00000000
r2 = 0xf0000002
r3 = 0x00000002

UMULL r0, r1, r2, r3 ; [r1,r0] = r2*r3

POSTr0 = 0xe0000004 ; = RdLo

r1 = 0x00000001 ; = RdHi
MUL r4,r2,r1 ;r4=r2*r1
MULS r4,r2,r1 ;r4=r2*r1,then
set the flags
MLA r7,r8,r9,r3 ;r7=r8*r9+r3

SMULL r4,r8,r2,r3 ;r4=bits of 31-0 of r2*r3


;r8=bits 63-32 of r2*r3
UMULL r6,r8,r0,r1 ;{r6,r8}=r0*r1
SMLAL r4,r8,r2,r3 ;r4=bits 31-0 of r2*r3+{r4,r8}
;r8=bits 63-32 of r2*r3+{r4,r8}
UMLAL r5,r8,r0,r1
;{r5,r8} = r0*r1+{r5,r8}

DISADV:
Uses multiplier array
Consumes more area and power
Slow
Single cycle or more
Solution :
Multiplication using barrel shifter
ADD r0,r1,r1,LSL #1 ;r0=r1*3
SUB r0,r0,r1,LSL #4 ;r0=r1*3-r1*16
=-r1*13
ADD r0,r0,r1,LSL #7 ;r0=-r1*13+r1*128
=r1*115
Branch Instructions
Syntax:
B{<cond>} label
BL{<cond>} label
BX{<cond>} Rm
BLX{<cond>} label | Rm
B branch
pc = label
BL branch with link
• pc = label
• lr = address of the next instruction after the BL
BX branch exchange
pc = Rm & 0xfffffffe, T = Rm &1
BLX branch exchange with link
• pc = label, T = 1
• pc = Rm & 0xfffffffe, T = Rm &1
• lr = address of the next instruction after the BLX
BL subroutine
CMP r1, #5
MOVEQ r1, #0
--
---
subroutine
<subroutine code>
MOV pc, lr ; return by moving pc = lr
Factorial of a given number
AREA Rotate, CODE, READONLY
ENTRY

MOV R6,#03
MOV R4,R6
LOOP SUBS R4,R4,#1
MULNE R7,R6,R4
MOV R6,R7
BNE LOOP

stop B stop
END
AREA Rotate, CODE, READONLY
ENTRY

MOV R6,#03 ;load num into r6


MOV R4,R6 ;copy num into a temp reg
LOOP SUBS R4,R4,#1 ;decrement next multiplier
MULNE R7,R6,R4 ;perform multiply
MOV R6,R7
BNE LOOP ;go again if not complete

stop B stop ;stop program


END
SWAP
A=A^B
B=A^B
A=A^B
swap
AREA Rotate, CODE, READONLY
ENTRY

LDR R0,=0XF631024C
LDR R1,=0X17539ABD
EOR R0,R0,R1 ;R0^R1
EOR R1,R0,R1 ;R1^R0
EOR R0,R0,R1 ;R0^R1

stop B stop ;stop program


END
R0=0X17539ABD
R1=0XF631024C
Load-Store Instructions

• three types of load-store instructions:


• single-register transfer,
• multiple-register transfer,
• and swap
Single-Register Transfer
• Syntax:
• <LDR|STR>{<cond>}{B} Rd,addressing1
• LDR{<cond>}SB|H|SH Rd, addressing2
• STR{<cond>}H Rd, addressing2
• LDR load word into a register
Rd <- mem32[address]
• STR save byte or word from a register
Rd -> mem32[address]
• LDRB load byte into a register
Rd <- mem8[address]
• STRB save byte from a register
Rd -> mem8[address]
AREA Rotate, CODE, READONLY
ENTRY
LDR R0,=0X40000000
MOV R1,#0X100
STR R1,[R0]
LDR R11,[R0]
stop B stop
;stop program
END
Single-Register Load-Store Addressing
Modes
Index methods:
preindex with writeback,
preindex,
and
postindex
Index method Data Base address Example
register
Preindex with mem[base + offset] base + offset LDR r0,[r1,#4]!
writeback
Preindex mem[base + offset] not updated LDR r0,[r1,#4]

Postindex mem[base] base + offset LDR r0,[r1],#4

! indicates that the instruction writes the calculated address back to the
base address register.
PRE r0 = 0x00000000
r1 = 0x00090000
mem32[0x00009000] = 0x01010101
mem32[0x00009004] = 0x02020202

LDR r0, [r1, #4]!

Preindexing with writeback:

POST(1) r0 = 0x02020202
r1 = 0x00009004

LDR r0, [r1, #4]

Preindexing:

POST(2) r0 = 0x02020202
r1 = 0x00009000

LDR r0, [r1], #4

Postindexing:

POST(3) r0 = 0x01010101
r1 = 0x00009004
Single-register load-store addressing,
word or unsigned byte.
Addressing1mode and index method Addressing1syntax

Preindex with immediate offset [Rn, #+/-offset_12]

Preindex with register offset [Rn, +/-Rm]

Preindex with scaled register offset [Rn, +/-Rm, shift #shift_imm]

Preindex writeback with immediate offset [Rn, #+/-offset_12]!

Preindex writeback with register offset [Rn, +/-Rm]!

Preindex writeback with scaled register [Rn, +/-Rm, shift #shift_imm]!


offset
Addressing1mode and index method Addressing1syntax

Immediate postindexed [Rn], #+/-offset_12

Register postindex [Rn], +/-Rm

Scaled register postindex [Rn], +/-Rm, shift #shift_imm


AREA Rotate, CODE, READONLY
ENTRY
LDR R0,=0X40000000
LDR R11,[R0],R2,LSL#02
stop B stop
;stop program
END
AREA Rotate, CODE, READONLY
ENTRY
LDR R0,=0X40000000
LDR R11,[R0],R2
stop B stop
;stop program
END
• The preindex mode is useful for accessing an
element in a data structure.
• The postindex and preindex with writeback
modes are useful for traversing an array.
Examples of LDR instructions using
different
Instruction
addressing
r0 =
modes.
r1 + =

Preindex LDR r0,[r1,#0x4]! mem32[r1 + 0x4] 0x4


with
writeback LDR r0,[r1,r2]! mem32[r1+r2] r2

LDR r0,[r1,r2,LSR#0x4]! mem32[r1 + (r2 LSR 0x4)] (r2 LSR 0x4)

Preindex LDR r0,[r1,#0x4] mem32[r1 + 0x4] not updated

LDR r0,[r1,r2] mem32[r1 + r2] not updated

LDR r0,[r1,-r2,LSR #0x4] mem32[r1-(r2 LSR 0x4)] not updated

Postindex LDR r0,[r1],#0x4 mem32[r1] 0x4

LDR r0,[r1],r2 mem32[r1] R2


AREA Rotate, CODE, READONLY
ENTRY
LDR R0,=0X40000000
LDRH R11,[R0]
stop B stop
END
0X40000000 = 0XFFAABBCC
R11=0X0000AAFF
AREA Rotate, CODE, READONLY
ENTRY
LDR R0,=0X40000000
LDRB R11,[R0]
stop B stop
END
0X40000000 = 0XFFFFFFFF
R11= 0x000000FF
AREA Rotate, CODE, READONLY
ENTRY
LDR R0,=0X40000000
LDRSH R11,[R0]
stop B stop
END
0X40000000 = 0X00FF8001
R11= 0xFFFFFF00
AREA Rotate, CODE, READONLY
ENTRY
LDR R0,=0X40000000
LDRSB R11,[R0]
stop B stop
END
0X40000000 = 0X80000000
R11= 0xFFFFFF80
AREA Rotate, CODE, READONLY
ENTRY
LDR R0,=0X40000000
STR R11,[R0]
stop B stop
;stop program
END
R11:0XFFFFFFFF
0X40000000=0XFFFFFFFF
AREA Rotate, CODE, READONLY
ENTRY
LDR R0,=0X40000000
STRH R11,[R0]
stop B stop
END
R11 = 0XAABBCCDD
0X40000000 = DDCC0000
AREA Rotate, CODE, READONLY
ENTRY
LDR R0,=0X40000000
STRB R11,[R0]
stop B stop
;stop program
END
R11:0XAABBCCDD
0X40000000 = DD000000
LOAD/STORE INSTRUCTIONS
LOADS STORES SIZE & TYPE

LDR STR WORD(32 BITS)

LDRB STRB BYTE(8 BITS)

LDRH STRH HALFWORD(16 BITS)

LDRSB -- SIGNED BYTE

LDRSH --- SIGNED HALFWORD

LDM STM MULTIPLE WORDS


IMM OFFSET REG OFFSET SCALED REG
OFFSET
WORD 12 BITS SUPPORTED SUPPORTED
UNSIGNED BYTE
HALFWORD 8 BITS SUPPORTED NOT SUPPORTED
SIGNED HALFWORD
SIGNED BYTE
Single-register load-store addressing, halfword, signed halfword, signed
byte.
Addressing2mode and index method Addressing2syntax

Preindex immediate offset [Rn, #+/-offset_8]

Preindex register offset [Rn, +/-Rm]

Preindex writeback immediate offset [Rn, #+/-offset_8]!

Preindex writeback register offset [Rn, +/-Rm]!

Immediate postindexed [Rn], #+/-offset_8

Register postindexed [Rn], +/-Rm


Instruction Result r1 + =

Preindex with STRH r0,[r1,#0x4]! mem16[r1+0x4]=r0 0x4


writeback
STRH r0,[r1,r2]! mem16[r1+r2]=r0 R2

Preindex STRH r0,[r1,#0x4] mem16[r1+0x4]=r0 not updated


STRH r0,[r1,r2] mem16[r1+r2]=r0 not updated
Postindex STRH r0,[r1],#0x4 mem16[r1]=r0 0x4
STRH r0,[r1],r2 mem16[r1]=r0 r2
PROGRAM TO MOVE A STRING OF CHARACTERS FROM ONE MEMORY TO ANOTHER

SRAM_BASE EQU 0X40000000


AREA Rotate, CODE, READONLY
ENTRY
MAIN
ADR R1,SRCSTR
LDR R0,=SRAM_BASE

STRCPY
LDRB R2,[R1],#1
STRB R2,[R0],#1
CMP R2,#0
BNE STRCPY
stop B stop
;stop program

SRCSTR DCB "HELLO",0


END
0X40000000 = 48 45 4C 4C 4F 00
CHANGING ENDIANNESS
MOV R2,#0XFF ;R2=0XFF
ORR R2,R2,#0XFF0000 ;R2=0X00FF00FF
MOV R3,R2,LSL #8 ;R3=0XFF00FF00
;R0=A B C D
AND R1,R2,R0,ROR #24 ;R1=0 C 0 A
AND R0,R3,R0,ROR #8 ;R0=D 0 B 0
ORR R0,R0,R1 ;R0 = D C B A
Multiple-Register Transfer
• can transfer multiple registers between memory
and the processor in a single instruction
• Load-store multiple instructions can increase
interrupt latency
• instruction takes 2 + Nt cycles,
– where N is the number of registers to load and t is the
number of cycles required for each sequential access
to memory
• If an interrupt has been raised, then it has no
effect until the load-store multiple instruction is
complete
Syntax: <LDM|STM>{<cond>}<addressing mode>
Rn{!},<registers>{ˆ}
• Rn  source or destination address for a load-
store multiple instruction
This register can be optionally updated following the
transfer.{!}

LDM load multiple registers {Rd}∗N <- mem32[start address +


4∗N] optional Rn updated

STM save multiple registers {Rd}∗N -> mem32[start address +


4∗N] optional Rn updated
LDMIA r0!, {r1-r3}

MEM DATA(LSBYTE)
4000000C 33
40000008 11
40000004 22
40000000 AA

R0=0X40000000 R1=AA
R0=0X40000004 R2=22
R0=0X40000008 R3=11
R0=0X4000000C
LDMIB r0!, {r1-r3}

MEM DATA(LSBYTE)
4000000C DD
40000008 CC
40000004 BB
40000000 AA

R0=0X40000000
R0=0X40000004 R1=BB
R0=0X40000008 R2=CC
R0=0X4000000C R3=DD
LDMDA r0!, {r1-r3}

MEM DATA(LSBYTE)
4000000C DD
40000008 CC
40000004 BB
40000000 AA

R0=0X4000000C R3=DD
R0=0X40000008 R2=CC
R0=0X40000004 R3=BB
R0=0X40000000
LDMDB r0!, {r1-r3}

MEM DATA(LSBYTE)
4000000C DD
40000008 CC
40000004 BB
40000000 AA

R0=0X4000000C
R0=0X40000008 R3=CC
R0=0X40000004 R2=BB
R0=0X40000000 R1=AA
STMIA r0!, {r1-r3}
R0=0X40000000
R1=0X00000011
R2=0X00000022
R3=0X40000033
R4=0X40000044
MEM DATA(LSBYTE)
4000000C
40000008 33
40000004 22
40000000 11

R0=0X4000000C
STMIB r0!, {r1-r3}
R0=0X40000000
R1=0X00000011
R2=0X00000022
R3=0X40000033
R4=0X40000044
MEM DATA(LSBYTE)
4000000C 33
40000008 22
40000004 11
40000000

R0=0X4000000C
STMDA r0!, {r1-r3}
R0=0X4000000C
R1=0X00000011
R2=0X00000022
R3=0X40000033
R4=0X40000044
MEM DATA(LSBYTE)
4000000C 33
40000008 22
40000004 11
40000000

R0=0X40000000
STMDB r0!, {r1-r3}
R0=0X4000000C
R1=0X00000011
R2=0X00000022
R3=0X40000033
R4=0X40000044
MEM DATA(LSBYTE)
4000000C
40000008 33
40000004 22
40000000 11

R0=0X40000000
Addressing Description Start address End address Rn!
mode

IA increment after Rn Rn + 4∗N − 4 Rn + 4∗N

IB increment before Rn + 4 Rn + 4∗N Rn + 4∗N

DA decrement after Rn − 4∗N+ 4 Rn Rn − 4∗N

DB decrement before Rn − 4∗N Rn − 4 Rn − 4∗N


Load-store multiple pairs when base update used

Store multiple Load multiple


STMIA LDMDB

STMIB LDMDA

STMDA LDMIB

STMDB LDMIA
BLOCK MOVE
AREA Rotate, CODE, READONLY
ENTRY
MOV R0,#08 ;NO OF WORDS TO MOVED
LDR R9,=0X40000000
LDR R10,=0X400000C0

LOOP LDMIA R9!,{R1-R4}


STMIA R10!,{R1-R4}

SUBS R0,#04
BGT LOOP
stop B stop ;stop program
BLOCK EXCHANGE
AREA Rotate, CODE, READONLY
ENTRY
MOV R0,#03
LDR R9,=0X40000000
LDR R10,=0X400000C0
MOV R2,#04

LOOP1 LDR R1,[R9]


LDR R3,[R10]
STR R1,[R10],r2
STR R3,[R9],r2

SUBS R0,#01
BGT LOOP1
stop B stop
Stack Operations
• uses the load-store multiple instructions
• The pop operation (removing data from a
stack) uses a load multiple instruction
• the push operation (placing data onto the
stack) uses a store multiple instruction
• the stack will grow up or down in memory.
• A stack is either ascending (A) or descending
(D)
• Ascending stacks grow towards higher
memory addresses
• descending stacks grow towards lower
memory addresses.
• Full stack (F), the stack pointer sp points to an
address that is the last used or full location
(i.e., sp points to the last item on the stack).
• empty stack (E) the sp points to an address
that is the first unused or empty location (i.e.,
it points after the last item on the stack).
Addressing Description Pop = LDM Push = STM
mode
FA full LDMFA LDMDA STMFA STMIB
ascending
FD full LDMFD LDMIA STMFD STMDB
descending

EA empty LDMEA LDMDB STMEA STMIA


ascending

ED empty LDMED LDMIB STMED STMDA


descending
PRE r1 = 0x00000002
r4 = 0x00000003
sp = 0x00080014

STMFD sp!, {r1,r4}

PRE Address Data


0x80018 0x00000001
SP  0x80014 0x00000002
0x80010 Empty
0x8000c Empty

POST r1 = 0x00000002 POST Address Data


r4 = 0x00000003 0x80018 0x00000001
sp = 0x0008000c 0x80014 0x00000002
0x80010 0x00000003
SP  0x8000c 0x00000002
PRE r1 = 0x00000002
r4 = 0x00000003
sp = 0x00080010

STMED sp!, {r1,r4}

PRE Address Data


0x80018 0x00000001
0x80014 0x00000002
SP  0x80010 Empty
0x8000c Empty
0x80008 Empty
POST r1 = 0x00000002 POST Address Data
r4 = 0x00000003 0x80018 0x00000001
sp = 0x00080008 0x80014 0x00000002
0x80010 0x00000003
0x8000c 0x00000002
SP  0x80008 Empty
Swap Instruction
• special case of a load-store instruction
• It swaps the contents of memory with the
contents of a register.
• atomic operation—it reads and writes a
location in the same bus operation preventing
any other instruction from reading or writing
to that location until it completes
Syntax: SWP{B}{<cond>} Rd,Rm,[Rn]

SWP swap a word between memory and a tmp = mem32[Rn]


register mem32[Rn] = Rm
Rd = tmp

SWPB swap a byte between memory and a tmp = mem8[Rn]


register mem8[Rn] = Rm
Rd = tmp
The swap instruction loads a word from memory into
register r0 and overwrites the memory with register r1.
PRE mem32[0x9000] = 0x12345678
r0 = 0x00000000
r1 = 0x11112222
r2 = 0x00009000

SWP r0, r1, [r2]

POST mem32[0x9000] = 0x11112222


r0 = 0x12345678
r1 = 0x11112222
r2 = 0x00009000

Potrebbero piacerti anche