Surviving the 8086 Assembly Course Part 2
The blog series which contains all the core components to know so that you can pass your 8086 assembly lab course
Coding assembly in emu8086
If you already know C assembly is basically a longer way of doing things. The procedures are the same but here we use jump
for branching and in C we specifically try not to use similar functionality with goto
. There are some more changes in assembly as well but the general gist of work is the same.
Starting template
Assembly will require us to use a standard and some skeleton or a standard template,
1
2
3
4
5
6
7
8
9
10
11
.MODEL SMALL
.STACK 100H
.DATA
; variable definition and initialization section
.CODE
MAIN PROC
; Code section
MAIN ENDP
END MAIN
we can see the four section model, stack, data and code. For most of our cases we do not need to use any other than .model small
and 100h
or 256bytes
of stack memory. and the rest of the things are basically template code. we can also include exiting from DOS in this if we want to as well but generally the program will still function without it. Here is the code to that,
1
2
3
; Exiting DOS
MOV AX, 4CH
INT 21h
Defining variables
In 8086 assembly the concepts of variable is quite different compared to traditional programming languages. For example, in her we have-
- byte
- word
- double word
- quad word
- arrays and others
they are generally defined in the data section of the code. The way to define them are -
1
2
3
4
5
6
7
8
9
10
11
.data
A DW 10 ; Define word
B DB 20 ; Define byte
C DB 'Hello, world!$' ; Define a string ('$' is the ending character in assembly)
D DW ? ; Define a variable with no value in them
; the dup derivative fills up the values in the array using the insert value
E DW 20 DUP(?) ; define an array of 20 words
BUFFER DB 255 ; define a buffer of max size 255 to take string input
DB ? ; actual size of the input string
DB 255 DUP(?) ; the value of the string input
F DW 10, 20, 30 ; another example of an array with no dup derivative
Taking a character input
To take input of a single character in 8086 assembly we generally use the DOS interrupter. In the DOS interrupter we need to use 01h
in the AH
register when calling the INT 21H
interrupter. In other word the code to take input is,
1
2
MOV AH, 01H
INT 21H
This take the input in the AL
register. We have to remember in this case and store it in a variable to work with this or even we can also convert this into the appropriate data we can later work with.
Outputting a single character
To output a single character we have to put the ASCII
value in the DL
register and we have to put 02h
in the AH
register and then call the interrupter with INT 21H
.
1
2
3
MOV AH, 02H
MOV DL, 'A'
INT 21H
Outputting string
Here is the code to print “Hello world!!”.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.MODEL SMALL
.STACK 200H
.DATA
MSG DB 'Hello World!!', '$' ; Defines a string with ending character
.CODE
MAIN PROC
; Initialize the data variables @ data
MOV AX, @DATA
MOV DS, AX
; Pringing the MSG
MOV AH, 09h
LEA DX, MSG
INT 21h
; Exiting the program
MOV AX, 4CH
INT 21h
MAIN ENDP
END MAIN
Program procedure -
- The program first defines a string variable named MSG with bytes filling them with
'Hello World!!', '$'
which means the memory indicated by MSG will containHello World!!$
where$
here is used as the string breaker. In C we use null character\0
and here we are using$
. - Then we initialize the variables defined in the data segment first in the code segment
- Then we write the proram to print a string varialble
- we set
ah
to09h
- we load effective address of the string to
dx
- call int 21h
- we set
This effectively calls the DOS interrupter to print whatever is in the memory untill it finds a $
in the DOS terminal.
- Then optional closing the DOS terminal
- Then we end the proram
Inputting a string
We need to make a buffer variable in the data segment of the code and then we can take input of a string untill we press enter
. The example code is
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
.MODEL SMALL
.STACK 100H
.DATA
BUFFER DB 255
DB ?
DB 255 DUP('$')
NEWLINE DB 0AH, 0DH, '$'
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
; Load the buffer in dx and take input
LEA DX, BUFFER
MOV AH, 0AH
INT 21H
; The input string is now stored in the buffer+2 address in the memory
; now print a newline
LEA DX, NEWLINE
MOV AH, 09H
INT 21H
; Now then let us print the input string back
LEA DX, BUFFER + 2
MOV AH, 09H
INT 21H
; And finally end the program
MOV AX, 4CH
INT 21H
MAIN ENDP
END MAIN
Example code : Hello User!!
Remember you can also use lowercase in 8086 assembly if the compiler you are using supports it as well. In our case we were using emu8086 and they do supports it. and if you have already run the previous program you can see some inconsistency, This is stemed from the fact that the string ending character $
does not automatically gets pushed at the end of the buffer string. So you have to manually add that to solve direct printing issues. Here is a program that takes in input user name and then gives output of the Hello, name!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
.model small
.stack 100h
.data
nameBuffer db 255
db ?
db 255 dup(?)
newline db 0dh, 0ah, '$'
prompt db 'Enter your name: $'
hello db 'Hello, $'
helloend db '!!!', 0dh, 0ah, '$'
.code
main proc
; initialize data
mov ax, @data
mov ds,ax
; Logic area
; input prompt
lea dx, prompt
mov ah, 09h
int 21h
; input section
lea dx, nameBuffer
mov ah, 0ah
int 21h
; add a '$' after the string
mov si, offset nemeBuffer + 1 ; si -> string counter address
mov cl, [si] ; cl -> value of si
mov si, offset nameBuffer + 2 ; si -> string address
xor ch, ch ; set ch to 0 and cl = length
add si, cx ; si -> larst char ptr
mov byte ptr [si], '$' ; write '$' at byte pointer at [si]
; print newline
lea dx, newline
mov ah, 09h
int 21h
; say hello
lea dx, hello
mov ah, 09h
int 21h
; add name with the hello
lea dx, nameBuffer + 2
mov ah, 09h
int 21h
; print helloend
lea dx, helloend
mov ah, 09h
int 21h
; print newline
lea dx, newline
mov ah, 09h
int 21h
; emd Process
mov ax, 4ch
int 21h
; Function area
; end Program
main endp
end main