Introduction
Assembly language is a programming language which allows you to communicate with the computer at a more fundamental level. The purpose of this article is to present a small project in Assembly for encrypting / decrypting text. This is not an in depth manual of assembly in any way. Only the more fundamental aspects of assembly will be discussed briefly here.
This project will present the use of very basic assembly instructions for 8/16 bit processors. The programs shown here are a twin set of encryption / decryption programs. The user just writes and the Huo11.exe program encrypts what he writes instantly. The user can use the decryption program (Huo12.exe) to do the opposite (decrypt the encrypted message). Pressing ‘q’ terminates the program.
Why should you read this? Well, there is an old Buddhist proverb saying "When the student is ready, the master appears". I am no master. And if you are not willing to be a student, then just go away and read something else. Graphics and sound are usually much more interesting...
Prerequisites
In order to be able to use this program, you will need:
- NASM Assembler which can be downloaded from http://www.nasm.us/.
- ALINK Linker which can be downloaded from http://alink.sourceforge.net/.
- A simple text editor (e.g. Notepad) to write your program.
- A DOS emulator for your hyper-modern computer (which can do a lot of things, but does not allow you to do a lot of things on your own...)
Note that for recent Windows versions, you might need a DOS emulator to be able to run these programs. A good such emulator is DoxBox, which can be downloaded from http://www.dosbox.com/. See the picture in the beginning of the article to see how you can mount a drive to DosBox and start NASM in cmd.
Distribution
You can download the following from here:
- The code for the “Encryption” program (Huo11.asm) and the final executable (Huo11.exe)
- The code for the “Decryption” program (Huo12.asm) and the final executable (Huo12.exe)
- The ALINK Linker and NASM16 Assembler which I used to compile and link the programs (along with manuals)
A Brief Introduction to Assembly
In order to control a computer, you have to control its memory. Its circuits are where the infamous 0s and 1s are stored and if you change them, you change the way the computer “thinks”. Memory in computers is stored in a specific way. Learn that way and you will know how to program. How to do that? Simple! Read the manual. It may sound like stupid advice, but it is not. Each processor has its own way of storing the data into its memory and its own memory schema. You just have to read the manufacturer’s manual in order to learn it.
What I will describe here is how memory was organized in the old DOS era for the 8086 processors. Why is that useful? Because it does not matter how memory is ACTUALLY organized. Technologies change every day! The main thing one has to learn is to be adaptable in that world of changes. Learn the memory model of a x8086 processor and you will have no trouble learning the memory model of a x80386 processor. Do that and going into Windows 7 / Pentium era will be no problem either. The key is not learning by heart how things work now, since tomorrow they will work in a different way. The key is to learn how to not be afraid to learn new things.
Memory Segments
Memory of an 8086/8088 processor was organized in great segments. Inside those segments, smaller sections existed. So in order to refer to a specific section of the memory, all you had to do was write down the “address” of the great segment and the displacement inside that segment so as to get to the specific section you want.
A memory address was in the form of TTTT:MMMM, where TTTT is the section and MMMM the displacement inside that section.
Registers
Some important sections of the memory had names. Those special places are called Registers. The main registers for 8086/8088 processors family are:
Registers set for 8086/8088 processors
Name | Category | Purpose |
AX | General purpose | Accumulator |
BX | General purpose | Base |
CX | General purpose | Counter |
DX | General purpose | Data |
SI | Index | Source index |
DI | Index | Ευρετήριο προορισμού |
SP | Stack | Stack pointer |
BP | Stack | Base pointer |
CS | Section | Code section |
DS | Section | Data Section |
SS | Section | Stack section |
ES | Section | Extra section |
IP | | Instruction pointer |
FLAGS | | Function flags |
You can move data into those registers (i.e. the section segments that those registers represent), with the move command. For example, the command...
mov DS, AX
...moves the data which reside into the AX memory section into the DS section.
These registers can be used to perform specific things. For example:
- DS register points to the data section of the program. If we load in the DS register, the section of our program’s data (e.g. with the commands
mov ax,data
and mov ds,ax
) and in the register DX, we load the displacement of a specific data element (variable) of our data (e.g. a variable named help with a command like mov dx,hello
), then the address DS:DX
points to the specific memory address of the hello
variable.
Another important section of memory is the Stack. In that section, you can push data or pop them out in order to use them again.
Interrupts
The operating system of DOS or the BIOS had some specific commands which were called interrupts and could be called with the… (surprise surprise) INT
command!
For example, the command...
INT 21h
...tells the program to look at the value stored in the AH
register to see what it will do.
In order to print a text message to the screen, you have to use the commands in bold in the section that follows:
Segment code
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,stacktop
mov dx, hello
mov ah,9
int 0x21
mov ax,0x4c00
int 0x21
segment data
hello: db 'hello, world', 13, 10, '$'
segment stack
stackresb 64
stacktop:
We load value 9 to AX register and then we call interrupt 0x21 (21h). The calling routine 9 of interrupt 21h is a DOC procedure which presents on the screen the data stored in the memory address stored in the DS:DX address.
I. The Encryption Program
The code of this program is here:
segment code
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,stacktop
%define encoderkey 'hello'
%strlen enkey encoderkey
main1:
mov ah,00
int 16h
mov dl,al
cmp al, 'q'
jz done
mov ah,enkey
add dl, ah
mov ah,2
int 0x21
jmp main1
done:
mov ax,0x4c00
int 0x21
segment data
segment stack stack
resb 64
stacktop:
Let me explain a bit.
The commands...
mov ah,00
int 16h
...instruct the program to wait for a key input from the user (this is what interrupt 16h
does when 0x00
is stored in AH register). The key entered is stored in DL register with the command: mov dl,al
.
The command...
cmp al, 'q'
jz done
...checks the value of the key pressed and if user pressed ‘q
’ then the program jumps to the command which terminated it (see below).
Commands...
mov ax,0x4c00
int 0x21
...are the ones which terminate the program (this is what interrupt 0x21
does with 0
in AX
register).
If the user has entered a character different than ‘q
’, then the program alters the value stored in DL
by adding the value of 5
to it (it actually transfers the length of the enkey
variable, which is 5
– this I did just for my own experimenting purposes):
mov ah,enkey
add dl, ah
and then it shows the resulting new character value in the screen:
mov ah,2
int 0x21
II. The Decryption Program
In order to decrypt the message, you just have to do the opposite: Just subtract the value of 5
from the character input! The code of the program is here:
segment code
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,stacktop
%define encoderkey 'hello'
%strlen enkey encoderkey
main1:
mov ah,00
int 16h
mov dl,al
cmp al, 'q'
jz done
mov ah,-5
add dl, ah
mov ah,2
int 0x21
jmp main1
done:
mov ax,0x4c00
int 0x21
segment data
segment stack stack
resb 64
stacktop:
Generally, you can create a simple assembly code file in Notepad and save it file with the name you want, using “.asm" as an extension. After you have written the program, all you have to do is compile it and then link it.
III. HuoCodec
I have merged both encryption and decryption functions in one program named HuoCodec. The source code of this program is actually a super-set of the programs presented above.
segment code
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,stacktop
%define encoderkey 'hello'
%strlen enkey encoderkey
main1:
mov dx,info1
mov ah,9
int 0x21
mov dx,info2
mov ah,9
int 0x21
mov dx,blankline
mov ah,9
int 0x21
mov dx,message1
mov ah,9
int 0x21
mov dx,message2
mov ah,9
int 0x21
mov dx,blankline
mov ah,9
int 0x21
select:
mov ah,00
int 16h
mov dl,al
cmp al, '1'
jz encrypt
cmp al,'2'
jz decrypt
encrypt:
mov dx,message3
mov ah,9
int 0x21
mov dx,blankline
mov ah,9
int 0x21
main_encrypt:
mov ah,00
int 16h
mov dl,al
cmp al, 'q'
jz done
mov ah,enkey
add dl, ah
mov ah,2
int 0x21
jmp main_encrypt
decrypt:
mov dx,message4
mov ah,9
int 0x21
mov dx,blankline
mov ah,9
int 0x21
main_decrypt:
mov ah,00
int 16h
mov dl,al
cmp al, 'q'
jz done
mov ah,-enkey
add dl, ah
mov ah,2
int 0x21
jmp main_decrypt
done:
mov ax,0x4c00
int 0x21
segment data
info1: db 'Huo CoDec - Programmed by Spiros Kakos (Huo)', 13, 10, '$'
info2: db '(c) Copyright 2005 - All rights reserved', 13, 10, '$'
blankline: db ' ', 13, 10, '$'
message1: db '1 - Encrypt message', 13, 10, '$'
message2: db '2 - Decrypt message', 13, 10, '$'
message3: db 'Encrypting mode (q to exit)...', 13, 10, '$'
message4: db 'Decrypting mode (q to exit)...', 13, 10, '$'
segment stack stack
resb 64
stacktop:
Compile the Programs
In DOS command line environment (that black and white screen which our children will unfortunately see only in encyclopedias, since all that kids do today with computers is browse, browse and.. oh, browse...), you must enter the appropriate command to compile the program that is written in assembly language (asm) in an objective file (.obj file which consists of assembly instruction mnemonics into opcodes). The assembly file must be located in the same directory with the assembler (which is NASM in our case).
NASM command for compiling:
nasm-f obj [filename] (e.g. nasm-f obj hello. asm)
Link the Program
Use ALINK to link the object files into one executable, by writing the command ALINK file2.obj file3.obj –oEXE
(or just ALINK [filename]) so as to link the file2.obj and file3.obj files into one EXE file (e.g. ALINK hello.obj
)
Conclusion
Just keep experimenting! And remember to play with the code a little bit before you ask another programmer how to do it. Because this is what actually makes a good programmer.