Post

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

Surviving the 8086 Assembly Course Part 2

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-

  1. byte
  2. word
  3. double word
  4. quad word
  5. 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

The output of the program is alt text

Program procedure -

  1. The program first defines a string variable named MSG with bytes filling them with 'Hello World!!', '$' which means the memory indicated by MSG will contain Hello World!!$ where $ here is used as the string breaker. In C we use null character \0 and here we are using $.
  2. Then we initialize the variables defined in the data segment first in the code segment
  3. Then we write the proram to print a string varialble
    1. we set ah to 09h
    2. we load effective address of the string to dx
    3. call int 21h

This effectively calls the DOS interrupter to print whatever is in the memory untill it finds a $ in the DOS terminal.

  1. Then optional closing the DOS terminal
  2. 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

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

Example code saying hello

This post is licensed under CC BY 4.0 by the author.