Tuesday, September 11, 2012

Perfect Lossless Encryption, is it possible?

At one point of time you may have asked yourself the question: "Is there any perfect lossless encryption algorithm that can compress ALL kinds of data?"

The short answer is no. There isn't such an algorithm that takes inputs of n bits and produces an output of y bits where n > y for all possible inputs.

You may immediately think of zipping or raring files and nearly all the time you get something smaller, and most of the time something, much, smaller. Well I am going to prove you that it's not possible.


Mathematical proof

A lossless encryption algorithm is mathematically a function, but a special type of function, a bijection. This is because the inverse of it must also be a function, if not this means the algorithm we are looking at is not lossless*.





Intuitive Explanation

Example 1) Let's try to design an algorithm for 2 bit strings, there are only 4 different inputs, which are
00, 01, 10, 11
but there are only 3 outputs:
null string, 0, 1
Now, how can we compress them to 1 and 0 bit? It is obvious when we think like that but this is true for all n, it is just not this obvious.

Example 2) Assume for a second we have a program which can compress anything, it doesn't have to be a super method which cuts the file size to half, but a just-fine method which drops file size at least by 1 bit. You give a 100 byte file and you get a file with 800-1=799 bits. Now what happens when you try to compress the resulting file? I mean giving the algorithm a 799 bit file and get a 798 bit file, remember we don't care what type of file that is, it might be compressed before or not. Do you see where this is going? If we compress that 800 times, we get a file with 0 bits. Can that be real?

One Last Point:

One of the first things came to my mind before thinking this through is,
"That might be possible, it doesn't have to go all the way to 0, because it can look like the graph of the function 1/x+n. Each time you compress it will get a little bit lower, but the graph should be asymptotic to a some constant file size." 
Do you see where this chain breaks? The thing that makes the previous statement meaningless is that there are infinite number of real numbers between any two real numbers, so a function may decrease over time for infinite time but not reach zero. Size of bitstrings are natural numbers. Even though there are infinitely many natural numbers, the thing what matters is the question "Are there infinitely many natural numbers between any two fixed natural numbers?" The answer is obviously no, this prevents us from thinking them like decreasing functions.



I am interested in hearing from you, what do you think is worth investigating and creating a simple brainstorming report?

*:At best case lossless, which is bad enough.

Saturday, September 8, 2012

Chess Bot for PlayChess

     As you know I have always been interested in automating things, so creating bots is a passion for me.I have created many bots for games, as well as for websites where you need to automate things. Any program that automates some process is defined as a bot for me.

     Notice that I didn't use the more common term Chess AI because I didn't create it. AI is just about making a decision where bots include scraping data, processing data and outputing data. Chess AI needs a well formatted board state, but if you are writing a chess bot for example for PlayChess.com you don't have the well defined structure in your hands. You need to somehow scrape the data out of it, either by memory reading which can get really tedious if developers added a security measure for it, or by image processing which is easier for most of the cases.

     If it wasn't a native application, and it was but a javascript web application there is a third and easier way, scraping and manipulating DOM. So writing bots for web applications are very easy compared to native applications with some security measures.

     I usually use C#.NET to write bots and most of my projects since I don't care about portability of my pet-projects.

     Part 1) Scraping the data via image processing


     I noticed that everytime I open a new chess game on playchess the board starts at the same pixel coordinates, so that saved me from a great work, I also noticed that the tiles are 64*64 pixels. So using the CopyFromScreen  function I copied the screen to a bitmap and tiled that to 64 bitmaps which are each 64*64 pixels.There are 13 types of tiles possible, 6 white pieces, 6 black pieces, and 1 empty tile. At first I identified all of these pieces uniquely through image processing. But then I realized I don't have to do that. The only thing I need to do is to identify the color of the tile, either white, or black or empty. Because I was creating a fully-autonomous bot, it will never involve in a game in the middle. I mean from the start on it will see all the positions. So if I know all the moves in terms of source and destination coordinates, and if I know the starting position which is well defined and static, so it is enough to know the only piece colors not the piece types. Because latter one can be derived from the known things. So I dropped out the unique piece determining and I continued with color identifying which is easier and more error-prone. This may only cause a problem when opponent is promoting a pawn, you wouldn't know which type of piece it is but it is queen 99% of the time. After getting the board position we must format it so we can pass it to the Chess AI if the AI is not written by us. (mine wasn't)

    Part 2) Passing the board state to a Chess AI


     Picking a Chess Engine is important, if you have your own engine that is good , you can probably connect that easily to your bot, but if that is not the case, you must use 2 functions, first one should convert the board state to a format that engine can understand, and the second one should convert the engine moves to a format that yours output layer can understand.

     If the engine you found is open-source your job is easier since you will obviously have access to code. I found crafty chess engine which is both open source, robust and powerful, you can find it here http://www.craftychess.com/ . But I don't use crafty's open source property, since crafty already gave me enough options. For example the command "output long" makes crafty to output moves like Nb1c3 which is easier to parse, normally chess moves are like Nc3, so you have to calculate the starting position which is a hard work for example when two pieces can move to the same location it gets even harder.
Another command "xboard" mutes crafty's unwanted data, it only outputs it's moves which is also better for us because we don't care about how many positions it analyzed and those kinds of information.

     I got crafty's exe and in my loop everytime a new game starts I start a process too, and redirect it's standart input and output to my C# program.

    Part 3) Passing the result of Chess AI to PlayChess client


     Now the last part is to make the move on the native application. You can try many things, you may intercept TCP packets and send your own tcp packets, or an easier way is to use Windows' SendMessage and SendInput API to make the move. I used this library http://inputsimulator.codeplex.com/ for it's simplicity for this project. You should turn the Chess AI's move output to source and destination coordinates, after that you can write a function like this and make your moves !!

public void makeMove(int r1, int c1, int r2, int c2)
        {
            InputSimulator inputsimul = new InputSimulator();
            inputsimul .Mouse.MoveMouseTo((c1*64+32+76) * (65535.0 / 1366.0), (r1*64+32+161) * (65535 / 768.0));
            System.Threading.Thread.Sleep(200);
             inputsimul  .Mouse.LeftButtonDown();
            System.Threading.Thread.Sleep(200);
             inputsimul  .Mouse.MoveMouseTo((c2 * 64 + 32 + 76) * (65535.0 / 1366.0), (r2 * 64 + 32 + 161) * (65535 / 768.0));
            System.Threading.Thread.Sleep(200);
             inputsimul  .Mouse.LeftButtonUp();
        }

This makes a drap-drop move from r1,c1 to r2,c2 where these variables represent tile coordinates, not pixel coordinates. +32 is used for clicking in the middle, 76 is offset of my board and the inputsimulator library takes input from 0 to 65535 where 65535 represents the maximum width or height of your screen.


Here is a video of my bot working,


http://www.youtube.com/watch?v=sjuB0__N8bE

Saturday, June 30, 2012

Very simple calculator with 8086

Hello, this is a project I made for learning. It should have many programming flaws, I didn't check and the comments are not enough. But it is working pretty well and it may be useful to somebody.

Here is a screenshot of it working;
                                        

The input format should be <integer><operator><integer>. Where <integer> is a value between 0 and 65535, and <operator> is a member of the set { + , - , * , /}.


And here is the code



CALL readdata
MOV BX, input
CALL printstr
CALL convertdata


MOV DI,input
MOV BX, SI
SUB BL,input
DEC BL 

begin:

CMP BL, 0
JNE morethanone
MOV CL,B[DI]
MOV CH,0h
ADD number1 W, CX
JMP finishconversion
morethanone:
MOV CL, BL
CALL expt
MOV CL, B[DI]
MOV CH, 0
MUL CX
ADD number1 W, AX
INC DI
DEC BL
JMP begin

finishconversion:



MOV DI, SI
INC DI
MOV BL, number2length B
DEC BL 

begin2:

CMP BL, 0
JNE morethanone2
MOV CL,B[DI]
MOV CH,0h
ADD number2 W, CX
JMP finishconversion2
morethanone2:
MOV CL, BL
CALL expt
MOV CL, B[DI]
MOV CH, 0
MUL CX
ADD number2 W, AX
INC DI
DEC BL
JMP begin2

finishconversion2:



MOV AX, number1 W
MOV BX, number2 W

CALL calculate

MOV result W, AX


CALL hextodecimal


MOV AH, 02h
MOV DL, '='
INT 21h

MOV DL, DH
CMP result W, 9999
JNG skip1
INT 21h
skip1:

MOV DL, CH
CMP result W, 999
JNG skip2
INT 21h
skip2:

MOV DL, CL
CMP result W, 99
JNG skip3
INT 21h
skip3:

MOV DL, BH
CMP result W, 9
JNG skip4
INT 21h
skip4:

MOV DL, BL
INT 21h

INT 20h


hextodecimal PROC

MOV     BX,0
MOV     CX,0
MOV     DH,0

convertloop2:

INC     BL               
CMP     BL,0Ah           
JNE     noripple         
MOV     BL,0             
INC     BH               
CMP     BH,0Ah           
JNE     noripple        
MOV     BH,0
INC     CL               
CMP     CL,0Ah
JNE     noripple
MOV     CL,0
INC     CH              
CMP     CH,0Ah
JNE     noripple
MOV     CH,0
INC     DH               


noripple:
DEC AX
CMP AX, 0h
JNE convertloop2

ADD DH, '0'
ADD CH, '0'
ADD CL, '0'
ADD BH, '0'
ADD BL, '0'

RET

hextodecimal ENDP


calculate PROC
ADD B[SI], '0' ; because we decreased it by 0's ascii value along with the other numbers..

CMP B[SI], '+'
JNE notAdd
ADD AX,BX
notAdd:
CMP B[SI], '-'
JNE notSub
SUB AX,BX
notSub:
CMP B[SI], '/'
JNE notDiv
MOV DX, 0h
DIV BX
notDiv:
CMP B[SI], '*'
JNE notMul
MUL BX
notMul:
RET
calculate ENDP





readdata PROC
MOV BX, input
MOV AH, 01h

readloop:
INT 21h
CMP AL, 13d
JE finishread

CMP AL, '0'
JNL jmpover
MOV SI, BX        ; we have the operators index in SI now
jmpover:

MOV B[BX], AL
INC BX

JMP readloop

finishread:
MOV B[BX], 0

sub BX, SI
DEC BX
MOV number2length B, BL

RET
readdata ENDP

convertdata PROC

MOV BX, input

convertloop:
CMP B[BX], 0
JE finishconvert

SUB B[BX], '0'
INC BX
JMP convertloop

finishconvert:

RET
convertdata ENDP


printstr PROC
myloop:
MOV AH, 02h ; we are setting it to print mode
MOV DL,[BX] ; we are moving the data located at the memory address BX to DL
CMP DL, 0h    ; we are checking if that data is 0
JE finish            ; if 0 we jump to finish and return
INT 21h           ; if not we output that data
INC BX           ; we are incrementing the memory location.
JMP myloop
finish:
RET
printstr ENDP

expt PROC
MOV AX, 10d

exptloop:
CMP CL, 1
JE exptfinish
MUL ten W
DEC CL
JMP exptloop

exptfinish:
RET
expt ENDP

ten:
dw 0Ah

number2length:
db 0

number1:
dw 0
number2:
dw 0


result:
dw 0

input:
db ?

Saturday, June 23, 2012

Introduction to Assembly (Part 3)


Now for the first time we are going to use memory to store data, there is a db directive which tells assembly compiler to place the operand right as it is to the memory. Notice the difference, it is a directive not an instruction. Directive is a thing for your compiler while the instructions are to be executed by the CPU. Normally when you write ADD your compiler translates this into the corresponding bytecode. An example will make it clearer for you to understand.

In this example I am going to use the db concept as well as direct addressing mode which is indicated by [] syntax, and procedure calls.

First of all have a look at this procedure:


printstr PROC
myloop:
MOV AH, 02h ; we are setting it to print mode
MOV DL,[BX] ; we are moving the data located at the memory address BX to DL
CMP DL, 0h    ; we are checking if that data is 0
JE finish            ; if 0 we jump to finish and return
INT 21h           ; if not we output that data
INC BX           ; we are incrementing the memory location.
JMP myloop
finish:
RET
printstr ENDP

Notice that MOV DL, BX and MOV DL, [BX] do completely different things. First copies the contents of the BX to DL, second copies the data located at the memory address of BX to DL.

So if we know we have a string starting at the address 0100h, you know that each character takes one byte. And one memory cell is one byte too, so the next character will be at the next address. We can access it by incrementing our current address. Notice that H e l l and o are placeholders for their ascii values while 0 is the exact 0 not the printable digit whichs ascii value is 48 if I am not mistaken. Because we are comparing with 0h not '0'.

0100h H
0101h e
0102h l
0103h l
0104h o
0105h 0h

If our memory looks like this we can do the following:

MOV BX, 0100h
CALL printstr

and voila! This will print Hello to screen. We need 0h because otherwise we wouldn't know when to stop. C does the same thing at the background when you create a string "Hello", it allocates 6 bytes, put the characters to first 5 bytes and adds a null to the end.

Now you may ask how are we going to allocate a memory like this, it's simple, with db directive!


message:
db 'Hello',0
message2:
db ' World!',0

message and message2 are labels. When we write 'Hello' to memory we need to know the address of it so we place a label before it. Remember labels give us the exact addresses of the next instruction. (This is not an instruction but uh.. you got it)

All together our code will look like this:




MOV BX, message
CALL printstr
MOV BX, message2
CALL printstr
INT 20h

message:
db 'Hello',0
message2:
db ' World!',0

printstr PROC
myloop:
MOV AH, 02h
MOV DL,[BX]
CMP DL, 0h
JE finish
INT 21h
INC BX
JMP myloop
finish:
RET
printstr ENDP

We are actually sending a parameter to printstr but not in a way you used to. Instead we place it into BX register and procedure uses that. This is how you transfer data between procedures in Assembly.

Now we know how to get data from the memory using brackets( [] ),  next I will show you how to edit the memory, for example let's design a program where you read input from the user and write it to the memory till user presses enter, and than echo it back to the user. For this we need an empty location where we can store our characters. Actually it doesnt have to be empty since we will overrite but empty in a manner that no one is going to use it. We wouldn't want to overwrite some meaningful bytecode.

Here is how we get a memory location in which we can write,
myspace:
db ?      ; ? means we don't care what is written there now, because we will overwrite it.

Actually saying something like db 'Hello this is a string' is completely OK too, because we won't read data from there which we didn't write.


MOV BX, message
CALL readstr
MOV BX, message ; we need to reset BX to the starting address since readstr procedure changes BX.
CALL printstr
INT 20h

readstr PROC
MOV AH, 01h ; set it to read mode
readloop:
INT 21h
CMP AL, 13d      ;if user pressed enter we finish reading.
JE readfinish
MOV [BX], AL
INC BX
JMP readloop
readfinish:
MOV B[BX],0h ; null-terminate our string, we need B[BX] because we want to store a 8-bit 0. not 16-bit zero.
RET
readstr ENDP

printstr PROC
printloop:
MOV AH, 02h
MOV DL,[BX]
CMP DL, 0h
JE printfinish
SUB DL, 32d    ; we are making the given lower case text to uppercase. 32 is 'a' - 'A'. if user enters upper characters this will print meaningless characters. But we don't check it here.
INT 21h
INC BX
JMP printloop
printfinish:
RET
printstr ENDP

message:
db ?

Now run the program and input something like "hello" and it will reply with "HELLO". After db ? don't put any more code or data. Because it only reserves one byte. So if you do something like this

db ?
db 'Hello'

the memory would look like this
0100h RANDOMDATA
0101h H
0102h e
..

So if you try to write something to 0100h more than one byte, it will overlap with Hello. But this is perfectly OK:

db 'Hello'
db ?

Because first directive knows how much bytes to reserve, you can write anything starting from the second one. Of course I omitted the labels here for convenience. But if you have the label for the first db you can find out the address of the location of the second directive, how? adding 5 to the first one. Because we know exactly how many bytes the first directive takes.

Now let's write a very simple calculator which can take 1 digit numbers and add, subtract, multiply and divide them. Later we will expand this to accept more than 1 digit numbers, but as a starting point let's consider this minimal case. Every query will be 3 characters long, in the form of
<integer><operator><integer>.
3+5, 4*2,2-1 are valid queries.



CALL readdata             ;read three characters and store them in first, operator and second.
CALL convertdata        ;convert the ascii values to actual values to be able to compute
CALL calculate            ;calculate the result and put it in BL

MOV AH, 02h    
MOV DL, '='
INT 21h
                                    ;then print =result
ADD BL, '0'
MOV DL, BL
INT 21h

INT 20h


myadd PROC
MOV BL, first B
ADD BL, second B
RET
myadd ENDP

mysub PROC
MOV BL, first B
SUB BL, second B
RET
mysub ENDP

mymul PROC
MOV AL, first B
MUL second B
MOV BL, AL
RET
mymul ENDP

mydiv PROC
MOV AH, 0h
MOV AL, first B
DIV second B
MOV BL, AL
RET
mydiv ENDP

calculate PROC
CMP operator B, '+'
JNE notAdd
CALL myadd
notAdd:
CMP operator B, '-'
JNE notSub
CALL mysub
notSub:
CMP operator B, '/'
JNE notDiv
CALL mydiv
notDiv:
CMP operator B, '*'
JNE notMul
CALL mymul
notMul:
RET
calculate ENDP


readdata PROC
MOV AH, 01h
INT 21h
MOV first B, AL
INT 21h
MOV operator B, AL
INT 21h
MOV second B, AL
RET
readdata ENDP

convertdata PROC
SUB first B, '0'      ;get the real numerical value instead of ascii value to do calculations
SUB second B, '0'
RET
convertdata ENDP

first:
db ?                  ;we were able to add more code after ? because we know that
operator:           ;we won't be putting more than one byte into these locations.
db ?
second:
db ?


If you examine the individual procedures one-by-one you should be able to understand the code.

Saturday, June 16, 2012

Introduction to Assembly (Part 2)


Now we can create some fancy structures, let's make a for loop.


MOV AX, 1d
MOV BX, 2d
MOV CX, 8d        ;you can use d suffix to represent decimal, it will be converted to hex 0Ah internally.
MYLOOP:            ;loop begin
MUL BX
DEC CX
CMP CX, 0
JNE MYLOOP    ;loop condition check
INT 20h


Can you see the for structure? Can you guess what does this code do?
C version of this code would look like
ax = 1;
bx = 2;
for(cx = 8; cx != 0; cx--)
ax = ax * bx;

ax will be 2^8 which is 0100 in hex.

Now that we know basic control structures and how to use registers, let's move on to I/O. Because I/O is about the operating system and a process can't do I/O on it's own. So we need to call System API or Interrupts in this case. Interrupts are called with the INT method. You already saw INT 20h, which indicates that our process has ended.

We will use INT 21h to get input from console, or to output something to console.
You can think of this as a function, but this function lacks two things, in assembly we can't give direct parameters to interrupts, neither they can return anything in a way you knew before. So our friends are registers as always.

By the time we call INT 21h, if there is 01h in the first 8 bits of the AX register (which is the significant part), we read a character from the standart input, and that characters ascii value is written into last 8 bits of the AX register. Else if there is 02h in the first 8 bits of the AX register, the character corresponding to the ascii value in the last 8 bits of the DX register is printed to the console.

Since sometimes we need to just use 8 bits of registers, assembly provides us with a feature which allows us to access the significant part of register A with writing AH and the least significant part with writing AL.(Ahigh and Alow) same applies for AX,BX,CX and DX registers. So if we change AH, AX changes, if we change AX, AH changes too. AX = AH (shifted to left 8 bits) + AL for all the time. Don't think you can store 3 different things in three of them. (There is no "3 of them" actually they all represent the same thing)

Let's print "Hello world!" to the screen.


MOV AH, 02h ; it is enough to set AH once.
MOV DL, 'H'
INT 21h
MOV DL, 'e'
INT 21h
MOV DL, 'l'
INT 21h
MOV DL, 'l'
INT 21h
MOV DL, 'o'
INT 21h
MOV DL, ' '
INT 21h
MOV DL, 'W'
INT 21h
MOV DL, 'o'
INT 21h
MOV DL, 'l'
INT 21h
MOV DL, 'd'
INT 21h
MOV DL, '!'
INT 21h
INT 20h

If we wanted to read characters in the middle we would have to change AH to 01h and then again to 02h to be able to output, but here we don't change the value of AH, so we don't need to set it again for each output.

Another interesting thing is we could use character literals like 'W' or 'd', this is because our compiler changes them to the corresponding ascii value, so
MOV DL, 'W'
does the same thing as
MOV DL, 057h
or
MOV DL, 87d

An ascii table assistance is needed sometimes, but we can get away from that whenever we can use character literals. It increases the readability greatly, isn't it?

How would you go about printing the entire alphabet? A while loop would be a good way to implement it. Let's make our while loop.

MOV AH, 02h
MOV DL, 'A'
PRINT:
INT 21h
INC DL
CMP DL, '['        ;This is the character comes after Z
JNE PRINT
INT 20h

This code is pretty straight forward and I know you understood it easily. We just used the techniques we learned, nothing new.

C version would be
ah = 2
dl = 'A'
do{
print;
}while(dl != '[');

Enough with outputting, let's get some input from the user.
First we will do a one char echoer.

FOREVER:
MOV AH, 01h
INT 21h         ; *
MOV AH,02h
MOV DL, AL ;Because the read character is written to AL, and we need it to be in DL to be output
INT 21h
JMP FOREVER

*:We don't need to move anything to DL because that is the output itself, DL will be overwritten.

This program reads a single character from the standart input and echoes it back to the std output. It is a blocking call which means if you don't type anything INT 21h will wait there till you enter a character. To exit this program you need to CTRL+C because we didn't add a finishing condition. Let's add a finishing condition to this loop.

NOTFOREVER:
MOV AH, 01h
INT 21h      
MOV AH,02h
MOV DL, AL
INT 21h
CMP 'q', AL
JNE NOTFOREVER

INT 20h

If you enter q, this program will terminate, but before terminating it will echo the 'q' too. If you consider this as a bug you can do the following:

NOTFOREVER:
MOV AH, 01h
INT 21h      
MOV AH,02h
CMP 'q', AL
JE FINISH
MOV DL, AL
INT 21h
JMP NOTFOREVER

FINISH:
INT 20h

This will control the character before outputing.

Now we can make a primitive guess a number game, only numbers allowed are 0 to 9

MOV CL, 5h  ; First let's forget about the "random" part and I'll explain it later.
ADD CL, 48d ; Add 48 to get the ascii value of the digit. This ease the comparison process.
MOV AH, 02h
MOV DL, 'P' ; P is our Please guess: notification
INT 21h
GUESS:
MOV AH, 01h
INT 21h        ; let's read a guess
CMP AL, CL ; compare the guess with our "random" number
JE CORRECT
JG GREATER
MOV AH, 02h
MOV DL, 'L'   ;L means the random number is less, input a smaller number
INT 21h
JMP GUESS
GREATER:
MOV AH, 02h
MOV DL, 'G'   ;G means the random number is greater, input a bigger number
INT 21h
JMP GUESS

CORRECT:
MOV AH, 02h
MOV DL, 'C'  ; C is our congratulations message
INT 21h
INT 20h

After you understand this program, there are two things lacking. One is random number, second is that the messages are only one character. Second one is because you know how to output multi-character messages from hello world, so you can translate this to a fully program with reasonable messages but I didn't want to do it because it would make the code much longer thus readability would suffer, and you may miss more important parts like control structures.

The first one is because random number generation is darn hard generally you would call a C function to give you a random data, or allocate a dynamic memory and use the garbage inside to use it as a seed. Anyway you have to design your own pseudo-random algorithm to make this work and it is way out of our scope for this tutorial. I am sorry that it isn't as easy as high-level languages, an interrupt would be nice if it put a random number in one of us registers, when we call it.

Now that we know the idea of JMPs, there is a more sophisticated version of JMP which is CALL. You can think of this as a function call, or more correctly a procedure call.

The syntax is as follows:

CALL myprocedure

myprocedure PROC
;Instructions
;Instructions
;Instructions
myprocedure ENDP

The special thing is instructions can contain the RET instruction which returns to the called place. You can do the "parameter passing" and "function return" with pointers

readchar PROC
MOV AH,01
INT 21h
RET
readchar ENDP

Now whenever you need to read a character you can do

CALL readchar

This means you can reduce two lines to a single line as well as increasing the readability of your code. If you are reading many characters in the code I would advise you to use this form. Of course you can do many more things with CALL instruction.

Saturday, June 9, 2012

Introduction to Assembly (Part 1)

Hello, this is Eralp Bayraktar, and today I am going to present you my assembly tutorial in which I will try to explain primitive instructions.

I will be using 8086 instruction set, since that is the most proper instruction set for beginners in my opinion.

Before getting our hands dirty with code, I will briefly explain the Von Neumann architecture, Addressing modes and registers. These are essential to be able to understand assembly language. 


Main aspect of Von Neumann architecture is that the data and the instructions are stored in the memory and by looking at only the current state of the memory one is not be able to differentiate instructions from data. But CPU has a register called PC (Program Counter) which keeps the address of the next instruction to be executed. This allows CPU to differentiate between data and instructions.For example if PC never points to a memory address, that can't be an instruction. It is either not used or data that is being manipulated. This architecture will be more clear when we start seeing some code.


Addressing modes allow us to specify how "parameters" are interpreted by the CPU. For example if you want to add 5 to the register A, (You can for now think registers as variables in high-level programming languages) There are few versions of this; You can add exactly 5 to the register A, or you can add the data in the memory address 5 to the register A. 
First one is called immediate addressing, while the second one is called direct addressing. (This might not seem to be direct to you since we are referring to a memory location but it is meaningful when considering the other addressing modes) I gave you only two addressing modes which are required and enough for this tutorial, but if you want to learn more about them you can always find more detailed information about them on the Internet.

Registers are very fast circuits that can store small amount of data, but have a very low access compared to memory references.
If you have been programming in a high-level language you can think of them as variables. Some of these variables are used by the CPU to get things done correctly while the others are "general purpose registers" which means you can hold any data you want in them. But the problem is they are only capable of storing 16 bits (In 8086 arch.) and we only have a few of them. (We are going to use AX,BX,CX and DX in this tutorial). Obviously 64 bits of data is not enough to code even basic programs so we will have to refer a lot to memory.

Simple instructions;
MOV AX, 0Fh
ADD AX,  0Fh
MOV BX, AX


These are simple instructions, one thing to mention is that the MOV command copies the right-value to left-location. ( MOV destination, source )
With this information we can say first instruction copies the value F to the register AX. (0xxxxxh means xxxxxx is a hex value, you better get used to hex values if you are going to program in assembly because it will make your life much easier)

Second instruction's syntax implies it's semantic which is  adding the value F to AX. Now AX holds the hex value 001e and binary value 0000 0000 0001 1110. Because a hex literal corresponds to 4 bits etc.

Third instruction copies the value in the register AX to BX. Now AX and BX hold both 001e.(see? it is easier than saying 0000000000011110, this is very error-prone)

Not all instructions have two operands, for example:
INC CX
DEC DX


Can you guess what they do? Yes they increment/decrement their operands value by 1. But we can't know what CX and DX hold now. (unless we inspect flags, which we will see soon)


There are also basic logic functions:
AND AX, BX
OR AX, BX
XOR AX, BX
NOT AX

I assume you know what these are, if not you can check their truth tables on the Internet. But these instructions check the bits of their operands one by one and give corresponding bits together to XXX gates. ( XXX = AND,OR or XOR)


There is also multiplication with the instruction MUL but this is a little bit counter-intuitive, we can't do for example:
MUL AX, 05h or MUL AX, BX
MUL only takes one operand, it expects to see the other operand on AX. So if you do
MUL 05h, the value of AX will be multiplied by 5.


You may be asking how am I going to multiply two constants then? This is how yo do it


MOV AX, constant1
MUL constant2


First you put AX the first operand and then call MUL constant2 which multiplies constant2 with AX which is constant1 and putting the result in AX.


There is also the second interesting thing, observer constant1 and constant2 can be 16 bit long which may make the product 32 bit long ! How is 32 bit product going to fit in 16-bit AX? The answer is it will not, instead CPU splits the product into two parts which are more significant part(High part) and less significant part(Low part) and puts High part to DX and Low part to AX. You can think that the DX+AX are continuous and the 32 bit product is written there.


This is the hardest part up to here, if you couldn't understand fully please read it again.


Another important thing when you are coding in assembly is LABEL's. They are not instructions nor they are interpreted by the CPU instead we use them as easy references to memory locations.

You will see codes like this:

START:
MOV AX, 05h
MOV BX, 06h
SECOND:
MUL BX

START and SECOND are labels. In this case the code does exactly the same thing with the code below. I mean EXACTLY, because unreferenced labels are simply discarded. And referenced labels are replaced by their addresses. So labels in general doesnt find a place in the generated bytecode.

MOV AX, 05h
MOV BX, 06h
MUL BX

So how does one reference a label? Meaningful way would be to use JMP but we will cover it later.
The answer is in many ways!


START:
MOV AX, SECOND
MOV BX, START
SECOND:
MUL BX

This code is perfectly fine. LABEL: INSTRUCTION means LABEL is the memory address of the following instruction. So they are just 16-bit numbers. Preprocessor runs over your code and replaces the references to labels with the memory addresses of the following instructions. So that code translates to this:

MOV AX, BEGINNING
MOV BX, BEGINNING+6
MUL BX


Here you see the labels are replaced by their "relative" addresses. +6 is there because SECOND comes after two add instructions which take up 3 bytes of memory each. So the third instruction can be inserted into BEGINNING + 6'th memory location. It is relative because Operating System can chose to place your machine code into an arbitrary memory location and give you a BEGINNING address which you can add values to it to get the desired locations.

In my compiler this code became for instance;

MOV AX, 0100h
MOV BX, 0106h
MUL BX
(so 0100 is just a "random" memory location for you)

But this usage of labels are not meaningful. We will now see JMP instruction which makes great use of labels combined with CMP instruction.

JMP takes a single operand ( generally a label in programs ) and sets PC to that value. Up to this point we wrote programs which linearly processed each instruction one by one starting from the BEGINNING. JMP changes the way this works.

MOV AX, 05h
MOV BX, 02h
JMP OVER
MOV BX, 03h
OVER:
MUL BX

Can you guess the value of BX after this code? A(2*5) or E(3*5)? Obviously A because JMP jumps to the OVER label not executing MOV BX,03h. So the third instruction never gets executed.
But this use of JMP is very static and we often need to have control over it to make meaningful things, there comes CMP instruction which means to compare.

CMP takes two operands and sets some "flags" according to it's operands. We will only consider the equality case but you can do much more with CMP and JMP instructions. There are many slightly modified JMP instructions namely

je <label> - Jump when equal
jne <label> - Jump when not equal
jz <label> - Jump when last result was zero
jg <label> - Jump when greater than
jge <label> - Jump when greater than or equal to
jl <label> - Jump when less than
jle <label> - Jump when less than or equal to 


MOV AX, 09h
CMP 0Ah, AX
JE EQUAL
MOV BX, 01h          ; part1
JMP FINISH            ;Why do we need this unconditional JMP?
EQUAL:
MOV BX, 02h          ;part2
FINISH:
INT 20h                    ;This is just a way to terminate the program.

This code means

if(0Ah == 09h)
execute part1
else
execute part2

If we didn't put the unconditional JMP it would mean

if(0Ah == 09h)
{execute part1}
execute part2

Observe that the part2 would get executed no matter what the result of the CMP is. This may be completely OK based on what are you trying to do, in the first code I wanted to create an if-else structure.

How does conditional JMP's know what they are going to do? They look at the flags raised by the last CMP command. But you don't have to think this in detail. Just use CMP and then a conditional JMP like JE or JNE.