In
line assembly
Assembler statements are recognized by the compiler.
The only exception is SWAP because this is a valid BASIC statement.
You must precede this ASM-statement with the !-sign so the compiler knows
that you mean the ASM SWAP statement.
Note that for the
ACC register, A is used in mnemonics.( Except for bit operations )
Example:
Mov
a, #10 'ok
Mov acc,#10 'also ok
but generates 1 more byte
Setb acc.0 'ok
Setb a.0 'NOT OK
You can also include
an assembler file with the $INCLUDE FILE.ASM statement.
The assembler is based
on the standard Intel mnemonics.
The following codes are used to describe the mnemonics:
Rn working register R0-R7
Direct 128 internal RAM locations, any IO port, control or status register.
For example : P1, P3, ACC
@Ri indirect internal RAM location addressed by register R0 or R1
#data 8-bit constant included in instruction
#data16 16-bit constant included in instruction
Bit 128 software flags, any IO pin, control or status bit
For example : ACC.0, P1.0, P1.1
Boolean
variable manipulation :
CLR C clear carry
flag
CLR bit clear direct bit
SETB C set carry flag
SETB bit set direct bit
CPL C complement carry flag
CPL bit complement direct bit
ANL C, bit AND direct bit to carry flag
ORL C,bit OR direct bit to carry flag
MOV C,bit Move direct bit to carry flag
Program
and machine control :
LCALL addr16 long
subroutine call
RET return from subroutine
RETI return from interrupt
LJMP addr16 long jump
SJMP rel short jump (relative address)
JMP @A+DPTR jump indirect relative to the DPTR
JZ rel jump if accu is zero
JNZ rel jump if accu is not zero
JC rel jump if carry flag is set
JNC rel jump if carry flag is not set
JB bit,rel jump if direct bit is set
JNB bit,rel jump if direct bit is not set
JBC bit,rel jump if direct bit is set & clear bit
CJNE A,direct,rel compare direct to A & jump of not equal
CJNE A,#data,rel comp. I'mmed. to A & jump if not equal
CJNE Rn,#data,rel comp. I'mmed. to reg. & jump if not equal
CJNE @Ri,#data,rel comp. I'mmed. to ind. & jump if not equal
DJNZ Rn,rel decrement register & jump if not zero
DJNZ direct,rel decrement direct & jump if not zero
NOP No operation
Arithmetic
operations :
ADD A,Rn add register
to accu
ADD A,direct add register byte to accu
ADD A,@Ri add indirect RAM to accu
ADD A,#data add immediate data to accu
ADDC A,Rn add register to accu with carry
ADDC A,direct add direct byte to accu with carry flag
ADDC A,@Ri add indirect RAM to accu with carry flag
ADDC A,#data add immediate data to accu with carry flag
SUBB A,Rn subtract register from A with borrow
SUBB A,direct subtract direct byte from A with borrow
SUBB A,@Ri subtract indirect RAM from A with borrow
SUBB A,#data subtract immediate data from A with borrow
INC A increment accumulator
INC Rn increment register
INC direct increment direct byte
INC@Ri increment indirect RAM
DEC A decrement accumulator
DEC Rn decrement register
DEC direct decrement direct byte
DEC@Ri decrement indirect RAM
INC DPTR increment datapointer
MUL AB multiply A & B
DIV AB divide A by B
DA A decimal adjust accu
Logical
operations :
ANL A,Rn AND register
to accu
ANL A,direct AND direct byte to accu
ANL A,@Ri AND indirect RAM to accu
ANL A,#data AND immediate data to accu
ANL direct,A AND accu to direct byte
ANL direct,#data AND immediate data to direct byte
ORL A,Rn OR register to accu
ORL A,direct OR direct byte to accu
ORL A,@Ri OR indirect RAM to accu
ORL A,#data OR immediate data to accu
ORL direct,A ORL accu to direct byte
ORL direct,#data ORL immediate data to direct byte
XRL A,Rn exclusive OR register to accu
XRL A,direct exclusive OR direct byte to accu
XRL A,@Ri exclusive OR indirect RAM to accu
XRL A,#data exclusive OR immediate data to accu
XRL direct,A exclusive OR accu to direct byte
XRL direct,#data exclusive OR immediate data to direct byte
CLR A clear accu
CPL A complement accu
RL A rotate accu left
RLC A rotate A left through the carry flag
RR A rotate accu right
RRC A rotate accu right through the carry flag
SWAP A swap nibbles within the accu
Data
transfer :
MOV A,Rn move register
to accu
MOV A,direct move direct byte to accu
MOV A,@Ri move indirect RAM to accu
MOV A,#data move immediate data to accu
MOV Rn,A move accu to register
MOV Rn,direct move direct byte to register
MOV Rn,#data move immediate data to register
MOV direct,A move accu to direct byte
MOV direct,Rn move register to direct byte
MOV direct,direct move direct byte to direct
MOV direct,@Ri move indirect RAM to direct byte
MOV direct,#data move immediate data to direct byte
MOV@Ri,A move accu to indirect RAM
MOV@Ri,direct move direct byte to indirect RAM
MOV@Ri,#data move immediate to indirect RAM
MOV DPTR,#data16 load datapointer with a 16-bit constant
MOVC A,@A+DPTR move code byte relative to DPTR to A
MOVC A,@A+PC move code byte relative to PC to A
MOVX A,@Ri move external RAM (8-bit) to A
MOVX A,@DPTR move external; RAM (16 bit) to A
MOVX@Ri,A move A to external RAM (8-bit)
MOVX@DPTR,A move A to external RAM (16-bit)
PUSH direct push direct byte onto stack
POP direct pop direct byte from stack
XCH A,Rn exchange register with accu
XCH A,direct exchange direct byte with accu
XCH A,@Ri exchange indirect RAM with A
XCHD A,@Ri exchange low-order digit ind. RAM w. A
How
to access labels from ASM.
Each label in BASCOM is changed into a period followed by the label name.
Example :
GOTO
Test
Test:
generated ASM code:
LJMP .Test
.Test:
When you are using
ASM-labels you can also precede them with the !-Sign so the label won't
be converted.
Jb P1.0, Test ; no period
!test : ;indicate ASM label
Or you can include
the period in the labelname.
Another good alternative is to use the $ASM $END ASM directives.
Example:
$Asm
mov a,#1
test:
sjmp test
$End Asm
How
variables are stored.
BIT variables are stored in bytes.
These bytes are stored from 20hex -2Fhex thus allowing 16 * 8 = 128 bit
variables.
You can access a bit variable as follows:
Dim
var As Bit 'dim variable
SETB {var} ; set bit
CLR {var} ; clear bit
Print var ; print value
End
Or you can use the
BASIC statement SET and RESET which do the same thing.
BYTE variables are stored after the BIT variables.
Starting at address
20 hex + (used bytes for bit vars).
INTEGER/WORD variables
are stored with the LSB at the lowest memory position.
LONG variables are stored with the LSB at the lowest memory position too.
You can access variables
by surrounding the variable with {.
To refer to the MSB of an Integer/Word use var+1.
To refer to the MSB of a Long use var+3.
The following example
shows how to access the variables from ASM
Dim
t as Byte, c as Integer
CLR a ; clear register
a
MOV {t} , a
; clear variable t
INC {t} ; t=t + 1
MOV {c} , {t} ; c =
t
MOV {c+0}, {t} ; LSB
of C = t (you don't have to enter the +0)
MOV {lain+1}, {t} ;
MSB of C = t
MOV {c},#10 ; assign
value
You
can also change SFRs from BASIC.
P1 = 12 'this is obvious
ACC = 5 'this is ok
too
f0 B = 3 'B is a SFR too
MUL AB
'acc = acc * b
Printcf0 acc
EXTERNAL variables
are stored similar.
Strings are stored with a terminating zero.
Example :
$RAMSTART
= 0
Dim s As String * 10
'reserve 10 bytes + 1 for string terminator
s = "abcde" 'assign string constant to string
ram location 0 = a
'first memory location
ram location 1 = b
ram location 2 = c
ram location 3 = d
ram location 4 = e
ram location 5 = #0
External variables must be accessed somewhat different.
Dim
T as XRAM Byte
mov
dptr,#{T} ; address of T to datapointer
mov a,#65 ; place A
into acc
movx @dptr,a
; move to external memory
Print T ; print it
from basic
Dim
T1 as XRAM Integer
mov dptr,#{T1} ; set
datapointer
mov a,#65 ; place A
into acc (LSB)
movx @dptr,a
; move to external memory
inc dptr ; move datapointer
mov a,#1 ; 1 to MSB
movx @dptr,a
; move to external memory
Print
T1 ; print it from basic
Helper routines
There are two new ASM helper routines that can make it a bit easier:
PLACEVALUE
var , SFR
PLACEADRES var, SFR
PLACEVALUE assigns
the variable, var, to the specified register, SFR.
Placevalue 1, A will generate :
Mov a,#1
Dim x as Byte
Placevalue x ,R0 will generate:
Mov a, h'3A ; in this example only of course
Where it is becoming
handy is with arrays :
Placevalue a(x), RO will generate :
Mov
r0,#h'3A
Mov a,@r0
Rl a
Add a,#h'1F
Mov R0,a
Mov a,@r0
These are all examples,
the generated code will differ with the type of variables used.
You can only assign
1 SFR with the PLACEVALUE statement.
This is where PLACEADRES comes around the corner.
Placeadres , places a variables address into a register.
Placeadres
ar(x),A
Placeadres z , R0
When external variables
are used, you don't need to specify a register because DPTR is always
assigned.
Dim
X as xram Integer
PLACEADRES x , dptr or PLACEADRES
x
Will generate :
Mov dptr,#2
Or with arrays
:
PLACEADRES
ar(x)
Mov
dptr,#2
Mov r0,#h'37
Mov
a,@r0
Mov r2,a
Inc r0
Mov a,@r0
Mov r3,a
Mov r1,#1
Acall _AddIndex
Of course these are
also examples, the generated code depends on the types and if they are
internal or external variables.
Hexdecimal
notation
You can also use hexadecimal notation.
Example : Mov
a,#h'AA
Or use the BASIC notation :
Mov a,#&HAA
Binary
notation
You can also use binary notation.
Example : Mov
a,#&B10001000
Jumping with offset
You can specify an offset
instead of a labelname when jumping.
Jb
P1.0 , *+12 ;jump forward
Jb P1.0 , *-12 ;jump
back
Jnb P1.0 , *+0 ;loop
until P1.0 becomes high
This also applies
to the other instructions where can be jumped to a label like SJMP, LJMP
DJNZ etc.
Internal
buffer for string conversion
The string conversion routines used for PRINT num , STR() and VAL(), use
an internal buffer of 16 bytes. This has the advantage that no stack handling
is needed but the disadvantage that a fixed space is used.
Of course you can
use this buffer. It can be referenced with ___TMP_S1
So when you need a temp string, you can use this buffer.
Note that this buffer is only available with the mentioned statements!
Example :
Dim s as single
s = 1.1
Print s 'now the buffer
is needed
___TMP_S1 = "Use this space"
Print ___TMP_S1
Comment
The ; sign can be used or the BASIC comment sign '
Mov a,#1 ; comment
Mov a,#2 'comment
|