Ammar wrote:
> Hi!
> Can anyone tell me how to declare 8-bit or 16-bit variables while
> programming in assembly language for 8051 microcontroller (AT89C51),
> using the on-chip RAM.
>
As mentioned in several of the responses, most assemblers will allow
you to declare variables of several types, but the programmer must
insure that the variables are used correctly.
A variable is generated at assembly time by reserving storage at an
address (Starting address of first byte, or bit) and may initialize it
with a value(s), or simply reserve space.
I used the metalink assembler to create an expansion to BASIC-52 and
created constants and tables required in my program, as well as the
tables, flags, and vector addresses required by the interpreter at the
addresses specified in the MCS-51 BASIC Manual.
The assembler and the manuals are available online, and the manual has
many more examples of code and calling conventions. Probably more than
you want to know!
The original program was developed on a BCC-52 with a ROMA+B and 32KB of
RAM. (ROMA+B was itself an 8KB expansion ROM, and contained the ASM,
editor, and many of the same type commands I was adding. The difference
is that ROMA+B cost $150+) The RAM was used by the assembler as working
storage, symbol tables, and the resulting program, which didn't allow
many labels. The part below was after I bought a PC and could use the
Metalink assembler!
My expansion was developed to provide a way to test assembler code from
within the BASIC interpreter, with a PC or a small terminal as the
console, which required several versions of the display output.
Below are several types of "variables" and constants in various formats
from the expansion ROM I wrote. The MAKE_TOKEN macro is defined below
the code examples, and shows how to generate a basic "structure" in this
assembler. You will need to see the BASIC manual to make sense of the
values and formats...
Enjoy.
Gary
========Code snipped from ROM expansion=========
$INCLUDE(MACRO.SRC) ; add new instruction macros
; VARIABLES WHICH CONTROL THE FORMAT AND CONTENT OF THE EXPANSION
; ROM.
;
SMALL_SCRN EQU 0 ; SHORTEN MOST DISPLAYS TO FIT ON 40 CHAR SCREENS
DEC_HDR EQU 0 ; MODIFIES THE DISPLAY WHEN USING THE DIS.COMMAND
; SET TO 0 TO REMOVE THE DECIMAL ADDRESS COLUMN AND
; EXPAND THE NUMBER OF DISPLAYED CHARACTERS/LINE
;
; GENERAL EQUATES FOR READABILITY
;
CR EQU 0DH ; C RETURN
LF EQU 0AH ; LINE FEED
ROM_EOM EQU 22H ; END OF DISPLAY TEXT IN ROM
;
; SELECTED OPBYTEs to BASIC
;
D_STR EQU 6 ; DISPLAY STRING (R3:R1=POINTER)
R_MSG EQU 52 ; FLAG BIT FOR ROM MSG
G_STR EQU 5 ; INPUT STRING (INTO BASIC LINE BUFFER)
D_CHR EQU 80H ; DISPLAY CHAR IN R5
D_HEX EQU 98H ; DISPLAY HEX
N_L0 EQU 36H ; BIT WHEN SET-SUPPRESS LEADING 0'S FOR D_HEX
L_CHR EQU 3FH ; LOOK AT NEXT CHAR IN BASIC BUFFER
G_CHR EQU 40H ; GET NEXT CHAR IN BASIC BUFFER & ADV POINTER
G_CON EQU 41H ; GET CHAR FROM CONSOLE PUT IN ACC
E_ARG EQU 39H ; EVALUATE EXP (BASIC BUFFER),PUSH ON ARG STACK
G_ARG EQU 1 ; POP (16BIT) VALUE FROM ARG STACK TO R3:R1
D_NL EQU 7 ; NEW LINE-SEND CR/LF TO CONSOLE
ORG 2000H ; EXTENSION STARTS AT 2000H
DB 00H
DB 00H
DB 5AH ; FLAG EXPANSION OPTION PRESENT
ORG 2048H ; CALLED BY BASIC WHEN INITIALIZING
SETB 45 ; FLAG EXPANSION HERE-FOR BASIC
JB 21H.7,NOT_COLD_START ; FIRST TIME?
SETB 21H.7 ; TO KEEP THE (c) FROM COMING UP AGAIN
AJMP C_WRITE ; PRINT THE COPYWRITE THIS TIME
NOT_COLD_START:
RET
ORG 2070H
MOV DPTR,#VECTOR_TABLE ; TELL BASIC WHERE JUMP TABLE IS
RET ; AND RETURN
ORG 2078H
MOV DPTR,#USER_TABLE ; USER TOKEN TABLE
RET
;
VECTOR_TABLE:
DW DO_DISPLAY ; ADDRESSES MUST BE IN THE SAME ORDER
DW HEX_L ; AS THE TOKENS!
DW BURN_EPROM ; BASIC USES " (TOKEN-10H)*2 "
DW MOV_MEM ; AS AN INDEX INTO THIS TABLE,
DW HELP ; WHICH MEANS YOU SHOULD NOT HAVE
DW FIL_BLK ; GAPS BETWEEN TOKEN #'S
DW VER_MEM
DW HEX_ERR ; GO TO AN EXIT CALL FOR DUMMY COMMAND
ORG VECTOR_TABLE+(2*17) ; RESERVE SPACE FOR MAX TOKENS
;
TOKEN_NUM SET 0FH ; BIAS FOR MAKE_TOKEN MACRO
USER_TABLE:
MAKE_TOKEN 'DIS.' ; DISPLAY CODE/DATA/EXTERNAL MEMORY
MAKE_TOKEN 'HEX.' ; LOAD/SEND INTEL HEXFILE
MAKE_TOKEN 'PRG.' ; PROGRAM AN EPROM/RAM
MAKE_TOKEN 'MOV.' ; MOVE BLOCKS OF MEMORY AROUND (SMART)
MAKE_TOKEN 'HELP' ; HELP COMMAND FOR EXTENSIONS
MAKE_TOKEN 'FIL.' ; FILL RAM WITH A PATTERN
MAKE_TOKEN 'VER.' ; VERIFY A MOVE/PRG WORKED
;
; ***** ADD NEW TOKENS HERE *****
;
LAST_TOK EQU TOKEN_NUM ; FOR USE BY HELP COMMAND/DUMMY TOKEN
DB LAST_TOK+1 ; WASTE A TOKEN BECAUSE OF ERRORS IN BASIC
DB 1FH,'dumy' ; DUMMY COMMAND, SEE ROMJ USER MANUAL!
DB 0FFH ; FLAG END OF USER EXPANSION
;
;
ORG 20E8H ; ALLOW EXPANSION OF TOKENS
HEX_L: ; LOAD AN INTEL HEX FILE
LJNB 47,DUMMY ; COMMAND MODE?
MOV 21H,#80H ; CLR FLAGS EXCEPT THE (C)
ACALL PEEK ; CHECK FOR SEND (L_CHR)
CJNE A,#'A',$+3 ; NUMBER?
JC HEX_N1 ; COULD BE
CLR ACC.5 ; MAKE UPPER CASE
CJNE A,#'L',$+7 ; LOAD?
ACALL GCI ; YES, WASTE CHAR (G_CHR)
.
.
==============end of ROM snipped==========================
MACRO.SRC
$NOLIST
; I am very lazy when it comes to rewrites of instructions after crossing
; page boundries. Each time the program I was working on became large
; enough to generate relative addressing errors, I only
; had to change the first character to correct the problem.
; example: SJMP => AJMP or AJMP => LJMP
;
AJNB MACRO BNUM,ADDR ;;CONVERT SJMP TO PAGE JUMP
JB BNUM,$+5
AJMP ADDR
ENDM
;
LJNB MACRO BNUM,ADDR ;;CONVERT PAGE JUMP TO LONG JUMP
JB BNUM,$+6 ;;THIS DESTROYS RELOCATION FEATURE!
LJMP ADDR
ENDM
;
AJB MACRO BNUM,ADDR ;;ALLOW JB 2K ACCESS
JNB BNUM,$+5
AJMP ADDR
ENDM
;
LJB MACRO BNUM,ADDR ;;ALLOW JB 64K ACCESS
JNB BNUM,$+6 ;;DESTROYS RELOCATION FEATURE
LJMP ADDR
ENDM
;
TJE MACRO REG,VALUE,ADDR ;;SJMP ON EQUAL
CJNE REG,VALUE,$+5
SJMP ADDR ; EQUAL
ENDM
;
ATJE MACRO REG,VALUE,ADDR ;;AJMP ON EQUAL
CJNE REG,VALUE,$+5
AJMP ADDR ; EQUAL
ENDM
;
ACJNE MACRO REG,VALUE,ADDR ;;ALLOW CJNE 2K ACCESS
CJNE REG,VALUE,$+5
SJMP $+4 ; EQUAL
AJMP ADDR ; NOT =
ENDM
;
TLE MACRO REG,VALUE,ADDR ;;MACRO DEF TO MAKE JUMP LESS THAN OR =
CJNE REG,VALUE+1,$+3
JC ADDR ; REG < OR = VALUE
ENDM
;
ATLE MACRO REG,VALUE,ADDR ;;MACRO DEF JUMP < OR =
CJNE REG,VALUE+1,$+3
JNC $+4
AJMP ADDR ; REG < OR = VALUE
ENDM
;
SCASE MACRO REG,VALUE,LESS,EQUAL,GREATER ;; ALL TESTS AT ONCE
CJNE REG,VALUE,$+3
JC LESS ; REG < VALUE
CJNE REG,VALUE+1,$+3
JC EQUAL ; REG = VALUE
SJMP GREATER ; REG > VALUE
ENDM
;
ACASE MACRO REG,VALUE,LESS,EQUAL,GREATER ;; ALL TESTS AT ONCE
CJNE REG,VALUE,$+3 ;; 2K RELOCATION
JNC $+4
AJMP LESS ; REG < VALUE
CJNE REG,VALUE+1,$+3
JC $+4
AJMP GREATER ; REG > VALUE
AJMP EQUAL ; REG = VALUE
ENDM
;
LCASE MACRO REG,VALUE,LESS,EQUAL,GREATER ;; ALL TESTS AT ONCE
CJNE REG,VALUE,$+3 ;; NO RELOCATION
JNC $+4
LJMP LESS ; REG < VALUE
CJNE REG,VALUE+1,$+3
JC $+4
LJMP GREATER ; REG > VALUE
LJMP EQUAL ; REG = VALUE
ENDM
;
;THE FOLLOWING LINE MUST BE ADDED TO THE BEGINNING OF THE EXPANSION PROG!
;TOKEN_NUM SET 0FH ; USER TOKENS START AT 10H
;
MAKE_TOKEN MACRO TOK_TXT ;; FORMAT BASIC-52 USER TOKEN
TOKEN_NUM SET TOKEN_NUM+1 ;; NEXT TOKEN # TO USE
DB TOKEN_NUM ;; THE TOKEN # FOR
DB TOK_TXT ;; TOK_TXT USER-TOKEN
DB 00H ;; END OF TOKEN
ENDM
$LIST