Storing data to discontinuous strings

Within Assembly like C/C++ you store strings as one continuous sequence of bytes in memory, well sometimes this isn’t always the case. In addition to changing the value in AX between executions of STOSW, you can change the destination address as well. The end result of this is that you are able to store data into several different areas of memory inside a very tight single loop.
Below is a small demo program and it is designed to clear the screen and then it will show a table that will contain all 256 ASCII characters in 4 lines, each line containing 64 characters. Within this table is the “undisplayable” ASCII characters whose values are below 32, these as some might know are control characters.
This program allows them to become displayable because it will write them directly into the video memory which means that both DOS and the BIOS know we are displaying control characters so they don’t get a chance to interpret or filter them with special meanings.


; Source name : ASCII.ASM
; Executable name : ASCII.COM
; Code model: : Real mode flat model

[BITS 16] ; Set 16 bit code generation
[ORG 0100H] ; Set code start address to 100h (COM file)

[SECTION .text] ; Section containing code

%include "MYLIB.MAC" ; Load in screen control macro library

START: ; This is where program execution begins:

Clear VidOrigin,0720H,4000 ; Clear full video buffer to spaces
; Show a 64-character rule above the table display:
Ruler VidOrigin,LineLen,ScrnWidth,0,LinesDown-1
les DI,[VidOrigin] ; Put vid seg in ES & offset in DI
add DI,ScrnWidth*LinesDown*2 ; Start table display down a ways
mov CX,256 ; There are 256 chars in the ASCII set
mov AX,0700H ; Start with char 0, attribute 7

DoLine: mov BL,LineLen ; Each line will consist of 64 characters
DoChar: stosw ; Note that there's no REP prefix!
jcxz AllDone ; When the full set is printed, quit
inc AL ; Bump the character value in AL up by 1
dec BL ; Decrement the line counter by one
loopnz DoChar ; Go back & do another char until BL goes to 0
add DI,(ScrnWidth - LineLen)*2 ; Move DI to start of next line
jmp DoLine ; Start display of the next line

AllDone: GotoXY 0,12 ; Move hardware cursor down below char. table
mov AH,4CH ; Terminate process DOS service
mov AL,0 ; Pass this value back to ERRORLEVEL
int 21H ; Control returns to DOS

[SECTION .data] ; Section containing initialised data

LRXY DW 184FH ; 18H = 24D; 4FH = 79D; 0-based XY of LR screen corner

VidOrigin DD 0B8000000H ; Change to 0B0000000H if you have a mono CRT!
CRLF DB 0DH,0AH

ScrnWidth EQU 80 ; Width of the screen in characters
LineLen EQU 64 ; Length of one line of the ASCII table
LinesDown EQU 4 ; Number of lines down to start ASCII table

The way in which i am calculating the offset from the beginning of the video refresh buffer is by letting assembly do the calculations whilst the program is being assembled with the following line.
add DI,ScrnWidth*LinesDown*2
What sort of an operand is ScrnWidth*LinesDown*2? I hear you ask. Weill the answer is that its a simple integer operand, no different from the value 1, 52 or 11,111. The key is to go back to the program and find out what ScrnWidth and LinesDown are. Some might think that these are variables in memory, defined with the DW operator but they aren’t, they are Equates(EQU). If you are confused as to what the differences are between EQU and DW, don’t worry about it as it stumps many a assembly programmer.
The DW and DB operators define and set aside areas of memory for storage of data, a DW exists somewhere at some address and only exists in one place. While the EQU, is a symbol you define mainly for the assembler’s use, it doesn’t set aside areas of memory and it doesn’t have a particular address, an example is this line taken from the program.
LinesDown EQU 4
In that example the value defines as LinesDown doesn’t exist at any single place in the program. It sets no storage because it is actually a notation in the symbol table, telling the assembler to substitute the value 4 for the symbol LinesDown anywhere it encounters that symbol.
When an assembler encounters any equates in a program, it performs a tetual change of the values assigned to the symbol defined in the equate. The assembler dumps the symbol and the value is slotted into the symbol’s place. Then the assembly of the program continues, using these substituted values instead of the symbols. In real terms the assembler is stopping to alter the source code when it gets to an equate and then it carries on with its task of assembling the program, the same as if the assembler was processing a macro.

Tags: ,

2 Responses to “Storing data to discontinuous strings”

  1. Good work! This is a good example of what can be done if only time is taken to make the post a quality one.

  2. calbayog says:

    Hi First time skipped here on your site, founde on ASK.

Leave a Reply