There are a lot of instructions in assembly but there are only about twenty that you have to know and will use very often. Most instructions are made up of three characters and have an operand then a comma then another operand. For example to put a data into a register you use the MOV
instruction.
mov ax,10 ; put 10 into ax mov bx,20 ; put 20 into bx mov cx,30 ; put 30 into cx mov dx,40 ; put 40 into dx
Notice that in assembler anything after a ;
(semicolon) is ignored. This is very useful for commenting your code.
You know about the stack but not how to put data in an out of it. There are two simple instructions that you need to know: push
and pop
. Here is the syntax for their use:
PUSH
: Puts a piece of data onto the top of the stack
Syntax: push data
POP
: Puts the piece of data from the top of the stack into a specified register or variable.
Syntax: pop register (or variable)
This example of code demonstrates how to use the push
and pop
instructions
push cx ; put cx on the stack push ax ; put ax on the stack pop cx ; put value from stack into cx pop ax ; put value from stack into ax
Notice that the values of CX and AX will be exchanged. There is an instruction to exchange two registers: XCHG
, which would reduce the previous fragment to „xchg ax,cx
“.
There are three types of operands in assembler: immediate, register and memory. Immediate is a number which will be known at compilation and will always be the same for example '20' or 'A'. A register operand is any general purpose or index register for example AX or SI. A memory operand is a variable which is stored in memory which will be covered later.
This is a list of some important instructions that you need to know before you can understand or write assembly programs.
MOV
: moves a value from one place to another.
Syntax: MOV destination, source
for example:
mov ax,10 ; moves an immediate value into ax mov bx,cx ; moves value from cx into bx mov dx,Number ; moves the value of Number into dx
INT
: calls a DOS or BIOS function which are subroutines to do things that we would rather not write a function for e.g. change video mode, open a file etc.
Syntax: INT interrupt number
For example:
int 21h ; Calls DOS service int 10h ; Calls the Video BIOS interrupt
Most interrupts have more than one function, this means that you have to pass a number to the function you want. This is usually put in AH. To print a message on the screen all you need to do is this:
mov ah,9 ; subroutine number 9 int 21h ; call the interrupt
But first you have to specify what to print. This function needs DS:DX
to be a far pointer to where the string is. The string has to be terminated with a dollar sign ($
). This would be easy if DS could be manipulated directly, to get round this we have to use AX.
This example shows how it works:
mov dx,OFFSET Message ; DX contains offset of message mov ax,SEG Message ; AX contains segment of message mov ds,ax ; DS:DX points to message mov ah,9 ; function 9 - display string int 21h ; call dos service
The words OFFSET
and SEG
tell the compiler that you want the segment or the offset of the message put in the register not the contents of the message. Now we know how to set up the code to display the message we need to declare the message. In the data segment we declare the message like this:
Message DB "Hello World!$"
Notice that the string is terminated with an dollar sign. What does 'DB' mean? DB is short for declare byte and the message is an array of bytes (an ASCII character takes up one byte). Data can be declared in a number of sizes: bytes (DB), words (DW) and double words (DD). You don't have to worry about double words at the moment as you need a 32-bit register, such as EAX, to fit them in.
Here are some examples of declaring data:
Number1 db ? Number2 dw ?
The question mark (?
) on the end means that the data isn't initialised i.e. it has no value in to start with. That could as easily be written as:
Number1 db 0 Number2 dw 1
This time Number1
is equal to 0 and Number2
is equal to 1 when you program loads. Your program will also be three bytes longer.
If you declare a variable as a word you cannot move the value of this variable into a 8-bit register and you can't declare a variable as a byte and move the value into a 16-bit register. For examples:
mov al,Number1 ; ok mov ax,Number1 ; error mov bx,Number2 ; ok mov bl,Number2 ; error
All you have to remember is that you can only put bytes into 8-bit registers and words into 16-bit registers.
Now that you know some basic instructions and a little about data it is time that we looked at a full assembly program which can be compiled.
; This is a simple program which displays "Hello World!" ; on the screen. .model small .stack 100h .data Message db "Hello World!$" ; message to be display .code start: mov dx,OFFSET Message ; offset of Message is in DX mov ax,SEG Message ; segment of Message is in AX mov ds,ax ; DS:DX points to string mov ah,9 ; function 9 - display string int 21h ; call dos service mov ax,4c00h ; return to dos DOS int 21h END start ;end here
These are some instructions to compile and link programs. If you have a compiler other than TASM or A86 then see your instruction manual.
tasm file.asm tlink file [/t]
The /t
switch makes a .COM file. This will only work if the memory model is declared as tiny in the source file.
a86 file.asm
This will compile your program to a .COM file. It doesn't matter what the memory model is.