Using assemly

Top  Previous  Next

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

B = 3                'B is a SFR too

MUL AB                'acc = acc * b

Print 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 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