ASMDATA/END ASMDATA statements  

Purpose

Define a block where primitive read-only data is stored.

Syntax

ASMDATA BlockName

  DB  1, "ABC"$,  0

  DW  2, "XYZ"$$, 0

  DD  &H12345678

  DQ  1234567890

END ASMDATA

Remarks

It is frequently convenient to define some data within the code section of your program.  This data is read-only, so it may never be altered.  An attempt to do so will result in a GPF (General Protection Fault), which will cause termination of your program.  This type of data is generally accessed only by ASM code.

Defined Data can be placed inside of a Sub, Function, Method, or Property using ASM statements, but there are a number of pitfalls to that technique.  When debugging, or when using TRACE, PROFILE, #DEBUG DISPLAY, ERL, ERL$, etc., PowerBASIC must insert special code in various places which makes if difficult (if not impossible) for you to access the data accurately.  You don't know the size of the inserted code, so you'll have some difficulty addressing it accurately.

An ASMDATA block solves that problem entirely.  It is designed for the sole purpose of defining data, and no extra code or extra data is ever inserted for any reason.  Data within the block is never aligned, so you always know the exact location of each item.  The ASMDATA block must be located outside of any Sub, Function, Method, or Property.  However, the BlockName you assign is public, so it may be referenced from any place in your program.  You may have one block on your program, or many.

By default, all ASMDATA blocks are positioned at the first available byte.  This allows contiguous blocks to be accessed as though they were one larger block.  You can align any or all of the blocks differently by preceding the block with an #ALIGN metastatement.

Labels and line numbers are not allowed in an ASMDATA block.  If you need a reference point to a particular sub-section of your data, just split it into two or more blocks, using each BlockName as the reference point.

The only statements allowed within an ASMDATA block are DB, DD, DQ, and DW, so they do not need to be preceded by an ASM statement.  An ANSI string literal expression may be placed in a DB statement, and a WIDE (unicode) string literal expression may be placed in a DW statement.  A string literal expression may consist of quoted string literals, string equates, and the concatenation operators (&,+).  You may also use CHR$(), SPACE$(), and STRING$() if they use only literal parameters.

You can access the address of an ASMDATA block with the CODEPTR() function.  So, if you create a block named ABC, like this:

ASMDATA ABC

  DB  5,2,3

  DB  7,8,9

END ASMDATA

You would access it something like this:

AsmVar = CODEPTR(ABC)

Another option is to access it directly to a CPU register of your choice by using one of these opcodes:

ASM LEA EBX, abc

ASM MOV EBX, Offset abc

This would result in moving the first data byte (5) into register AL.

Or even move it directly to a 32-bit variable:

ASM MOV   AsmVar, Offset abc

See also

ASM