Variables and Strings
In this the fourth tutorial we will cover how do allocate space in memory for variables in out programs and also how output messages on the screen using strings. This whole topic is very basic and very simple, as well as being essential to do anything useful in assembler
Unlike other assemblers, a86 does not specifically require a special area in the program where variables are declared, filled with keywords to remember. However it is good practice to have all your variables grouped together at the start of your program, so as to have a clear separation between variables and code. In assembler there are two “keywords” of sorts to remember: DB and DW. DB tells the compiler to allocate a byte space (8 bits) for a variable, while DW allocates two bytes (16 bits) for the variable. Characters and small numbers are allocated with db while most numbers for arithmetic are dw.
Once variables are declared, they can then be used like registers, with the mov instruction to transfer data. Here is an example of the program from tutorial 3 with a variable to hold each bracket:
jmp start ; First instruction should be a command ;======================= ; Data declarations clearly separated from code leftbr db "(" ; The variables declared to hold the brackets rightbr db ")" ; are given them as initial values. key db ; Variable declared to hold the key pressed ;======================= start: ; Program execution starts here... mov ah,08 int 21h ; Read a keypress mov key,al ; Store the key in the variable output: mov dl,leftbr ; Move the variable to dl for output mov ah,02 int 21h ; Output "(" mov dl,key int 21h ; Ouput key mov dl,rightbr int 21h ; Output ")" exit: mov ah,4ch mov al,00 ; Exit code 0 int 21h ; Terminate program |
Strings and arrays can be declared in assembler too, by a number of methods. The easiest method involves simply assigning more than one character to a data item, and voila – a string. This allows us to output messages easily, like in a basic “hello world” program:
jmp start ; Start program... ;============================ msg db "Hello World.$" ; A string variable with a value. ;============================ start: mov ah,09 ; subfunction 9 output a string mov dx,offset msg ; DX points to (holds the address of) the string int 21h ; Output the message exit: mov ah,4ch mov al,00 ; Exit code 0 int 21h ; Terminate program
|
There are a couple of things to notice about the above program, and about outputing strings in general. Firstly, when using interrupt 21h, sub-fn 9 to output strings, one must finish the string with a “$”. Otherwise the computer will continue outputing charaters from memory past the end of the string until a “$” is reached. The second thing to notice is that you do not move the string to DX, but you move the address of the string to the register. In the actual specification, it says that DS:DX must point to the address. This means that DS must contain the segment in which the string is, and DX holds the offset, or the address within that segment. However, as I mentionned in previous tutorials, when writing basic programs using a86, all the data and code is in one segment so you can forget about the DS requirement. (If you don’t follow this don’t worry, you can still write simple assembler code without knowing it!)
When one outputs a string in assembler, the computer does not automatically move onto the next line before the next output. It will continue outputting on the same line until that line is full, which means until 80 characters have been output. To force a line break, insert the line feed and carriage return characters in your string – characters 10 and 13. To display “Hello World” on screen and move onto the next line declare the variable msg as follows:
msg db "Hello World.",10,13,"$"
Non-printing characters like the carriage return, have to be added to a string by way of their character numbers. Character numbers are not placed in inverted commas in the definition, and must be separated by commas.