Thursday, December 15, 2011

ASM

                         :::::::::   ::::::::  :::::::::  ::::::::::
                         :+:    :+: :+:    :+: :+:    :+: :+:       
                         +:+    +:+ +:+        +:+    +:+ +:+       
                         +#++:++#+  +#++:++#++ +#++:++#:  :#::+::#  
                         +#+    +#+        +#+ +#+    +#+ +#+       
                         #+#    #+# #+#    #+# #+#    #+# #+#       
                         #########   ########  ###    ### ### 
                        
                                 http://blacksun.box.sk
                                   ____________________
           _______________________I      Topic:        I_____________________
          \                       I   Sk00l m3 ASM!!   I                    /
           \     E-mail:          I                    I   Written by:     /
            >                     I                    I                  <
           /    fu@ckz.org        I____________________I      Ralph        \
          /___________________________>           <_________________________\        

Sk00l m3 ASM!!#@$!@#

by Ralph (fu@ckz.org)
    -AWC (http://awc.rejects.net)
Version: 0.841
Date: 7/23/00

NOTE:  This thing is almost done, just gotta finish of the Win32 section, however I
       started working on other shit so finishing this is kinda 10th on my priority
       list.  If you think you can convince me to finish it sooner, feel free to
       contact me.

TOC

1.  Introduction
    -What is it?
    -Why learn it?
    -What will this tutorial teach you?

2.  Memory
    -Number Systems
      -Decimal
      -Binary
      -Hexadecimal
    -Bits, Nybbles, Bytes, Words, Double Words
    -The Stack
    -Segment:Offset
    -Registers

3.  Getting started
    -Getting an assembler
    -Program layout
     -.COM
     -.EXE

4.  Basic ASM
    -Basic Register operations
    -Stack operations
    -Arithmetic operations
    -Bit wise operation
    -Interrupts

5.  Tools
    -Debug
    -CodeView

6.  More basics
    -.COM file format
    -Flow control operations
    -Loops
    -Variables
    -Arrays
    -String Operations
    -Sub-Procedures
    -User Input

7.  Basics of Graphics
    -Using interrupts
    -Writing directly to the VRAM
    -A line drawing program

8.  Basics of File Operations
    -File Handles
    -Reading files
    -Creating files
    -Search operations

9.  Basics of Win32
    -Introduction
    -Tools
    -A Message Box
    -A Window

Appendix A
    -Resources

Appendix B
    -Credits, Contact information, Other shit

1.  Introduction
================

What is it?
-----------
Assembly language is a low-level programming language.  The syntax is nothing like
C/C++, Pascal, Basic, or anything else you might be used to.

Why learn it?
-------------
If you ask someone these days what the advantage of assembly is, they will tell you it's
speed.  That might have been true in the days of BASIC or Pascal, but today a C/C++
program compiled with an optimized compiler is as fast, or even faster than the same
algorithm in assembly.  According to many people assembly is dead.  So why bother
learning it?
1.  Learning assembly will help you better understand just how a computer works.
2.  If windows crashes, it usually returns the location/action that caused the error.
    However, it doesn't return it in C/C++.  Knowing assembly is the only way to track
    down bugs/exploits and fix them.
3.  How often do you whish you could just get rid of that stupid nag screen in that
    shareware app you use?  Knowing a high-level language wont get you very far when you
    open the shit up in your decompiler and see something like CMP EAX, 7C0A
4.  Certain low level and hardware situations still require assembly
5.  If you need precise control over what your program is doing, a high level language
    is seldom powerful enough.
6.  Anyway you put it, even the most optimized high level language compiler is still
    just a general compiler, thus the code it produces is also general/slow code.  If
    you have a specific task, it will run faster in optimized assembly than in any other
    language.
7.  "Professional Assembly Programmer"  looks damn good on a resume.
My personal reason why I think assembly is the best language is the fact that you're
in control.  Yes all you C/C++/Pascal/Perl/etc coders out there, in all your fancy
high level languages you're still the passenger.  The compiler and the language itself
limit you.  In assembly you're only limited by the hardware you own.  You control the
CPU and memory, not the otherway around.

What will this tutorial teach you?
----------------------------------
I tryed to make this an introduction to assembly, so I'm starting from the beginning.
After you've read this you should know enough about assembly to develop graphics
routines, make something like a simple database application, accept user input,
make Win32 GUIs, use organized and reuseable code, know about different data types
and how to use them, some basic I/O shit, etc.

2.  Memory
==========
In this chapter I will ask you to take a whole new look at computers.  To many they
are just boxes that allow you to get on the net, play games, etc.  Forget all that
today and think of them as what they really are, Big Calculators.  All a computer does
is Bit Manipulation.  That is, it can turn certain bits on and off.  A computer can't
even do all arithmetic operations.  All it can do is add.  Subtraction is achieved
by adding negative numbers, multiplication is repeaded adding, and dividing is
repeaded adding of negative numbers.

Number systems
--------------
All of you are familiar with at least one number system, Decimal.  In this chapter I
will introduce you to 2 more, Binary and Hexadecimal.

Decimal
Before we get into the other 2 systems, lets review the decimal system.  The decimal
system is a base 10 system, meaning that it consists of 10 numbers that are used to make
up all other number.  These 10 numbers are 0-9.  Lets use the number 125 as an example:
               Hundreds     Tens     Units
Digit             1          2         5
Meaning         1x10^2     2x10^1    5x10^0
Value            100         20        5
NOTE: x^y means x to the power of y.  ex. 13^3  means 13 to the power of 3 (2197)
Add the values up and you get 125.

Make sure you understand all this before going on to the binary system!

Binary
The binary systems looks harder than decimal at first, but is infact quite a bit easier
since it's only base 2 (0-1).  Remember that in decimal you go "value x 10^position" to
get the real number, well in binary you go "value x 2^position" to get the answer. 
Sounds more complicated than it is.  To better understand this, lets to some converting.
Take the binary number 10110:
1 x 2^4 = 16
0 x 2^3 = 0
1 x 2^2 = 4
1 x 2^1 = 2
0 x 2^0 = 0
Answer:  22

NOTE: for the next example I already converted the Ax2^B stuff to the real value:
      2^0 = 1
      2^1 = 2
      2^2 = 4
      2^3 = 8
      2^4 = 16
      2^5 = 32
      etc....

Lets use 111101:
1 x 32 = 32
1 x 16 = 16
1 x  8 =  8
1 x  4 =  4
0 x  2 =  0
1 x  1 =  1
Answer:  61

Make up some binary numbers and convert them to decimal to practise this.  It is very
important that you completely understand this concept.  If you don't, check Appendix B
for links and read up on this topic BEFORE going on!

Now lets convert decimal to binary, take a look at the example below:
238 / 2  remainder: 0
119 / 2  remainder: 1
59  / 2  remainder: 1
29  / 2  remainder: 1
14  / 2  remainder: 0
7   / 2  remainder: 1
3   / 2  remainder: 1
1   / 2  remainder: 1
0   / 2  remainder: 0
Answer: 11101110

Lets go through this:
1.  Divide the original number by 2, if it divides evenly the remainder is 0
2.  Divide the answer from the previous calculation (119) by 2.  If it wont
    divide evenly the remainder is 1.
3.  Round the number from the previous calculation DOWN (59), and divide it by 2.
    Answer: 29, remainder: 1
4.  Repeat until you get to 0....
The final answer should be 011101110, notice how the answer given is missing the 1st 0?
That's because just like in decimal, they have no value and can be omitted (023 = 23).

Practise this with some other decimal numbers, and check it by converting your answer
back to binary.  Again make sure you get this before going on!

A few additional things about binary:
* Usually 1 represents TRUE, and 0 FALSE
* When writing binary, keep the number in multiples of 4
  ex.  DON'T write 11001, change it to 00011001, remember that the 0 in front
  are not worth anything
* Usually you add a b after the number to signal the fact that it is a binary number
  ex. 00011001 = 00011001b

Hexadecimal
Some of you may have notice some consistency in things like RAM for example.  They seem
to always be a multiple of 4.  For example, it is common to have 128 megs of RAM, but
you wont find 127 anywhere.  That's because computer like to use multiples of 2, 4, 8,
16, 32, 64 etc.  That's where hexadecimal comes in.  Since hexadecimal is base 16, it is
perfect for computers.  If you understood the binary section earlier, you should have
no problems with this one.  Look at the table below, and try to memorize it.  It's not
as hard as it looks.
Hexadecimal        Decimal        Binary
0h                  0             0000b
1h                  1             0001b
2h                  2             0010b
3h                  3             0011b
4h                  4             0100b
5h                  5             0101b
6h                  6             0110b
7h                  7             0111b
8h                  8             1000b
9h                  9             1001b
Ah                 10             1010b
Bh                 11             1011b
Ch                 12             1100b
Dh                 13             1101b
Eh                 14             1110b
Fh                 15             1111b

NOTE:  the h after each hexadecimal number stands for <insert guess here>

Now lets do some converting:
Hexadecimal to Decimal
2A4F

F x 16^0 = 15 x 1    = 15
4 x 16^1 =  4 x 16   = 64
A x 16^2 = 10 x 256  = 2560
2 x 16^3 =  2 x 4096 = 8192
Answer: 10831

1.  Write down the hexadecimal number starting from the last digit
2.  Change each hexadecimal number to decimal and times them by 16^postion
3.  Add all final numbers up

Confused?  Lets do another example: DEAD
D x 1    = 13 x 1    = 13
A x 16   = 10 x 16   = 160
E x 256  = 14 x 256  = 3584
D x 4096 = 13 x 4096 = 53248
Answer: 57005

Practise this method until you get it, then move on.

Decimal to Hexadecimal
Study the following example:
1324

1324 /   16 = 82.75
  82 x   16 = 1312
1324 - 1312 = 12, converted to Hexadecimal: C

82 / 16 =  5.125
5 x 16 = 80
82 - 80 =  2, converted to Hexadecimal: 2

5 / 16 = 0.3125
0 x 16 = 0
5 -  0 = 5, converted to Hexadecimal: 5

Answer: 52C

I'd do another example, but it's too much of a pain in the ass, maybe some other time.

Learn this section you WILL need it!
This was already one of the hardest parts, the next sections should be a bit easier

Some additional things abot hexidecimal
1.  It's not uncommon to say "hex" instead of "hexidecimal" even thechnicaly speaking
    "hex" means 6, not 16.
2.  Keep hexidecimal numbers in multiples of 4, adding zeros as necessary
3.  Most assemblers can't handle numbers that start with a "letter" because they don't
    know if you mean a label, instruction, etc.  In that case there are a number of
    other ways you can express the number.  The most common are:
    DEAD = 0DEADh  (Usually used for DOS/Win)
    and
    DEAD = 0xDEAD  (Usually used for *Nix based systems)
    Consult your assembler's manual to see what it uses.

By the way, does anyone think I should add Octal to this...?

Bits, Nibbles, Bytes, Words, Double Words
-----------------------------------------
Bits are the smallest unit of data on a computer.  Each bit can only represent 2 numbers,
1 and 0.  Bits are fairly useless because they're so damn small so we got the nibble.
A nibble is a collection of 4 bits.  That might not seem very interesting, but remember
how all 16 hexadecimal numbers can be represented with a set of 4 binary numbers? 
That's pretty much all a nibble is good for.

The most important data structure used by your computer is a Byte.  A byte is the
smallest unit that can be accessed by your processor.  It is made up of 8 bits, or
2 nibbles.  Everything you store on your hard drive, send with your modem, etc is in
bytes.  For example, lets say you store the number 170 on your hard drive, it would look
like this:

+---+---+---+---+---+---+---+---+
| 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
+---+---+---+---+---+---+---+---+
  7   6   5   4   3   2   1   0
  H.O Nibble    |   L.O Nibble   

10101010 is 170 in binary.  Since we can fit 2 nibbles in a byte, we can also refer
to bits 0-3 as the Low Order Nibble, and 4-7 as the High Order Nibble
Next we got Words.  A word is simply 2 bytes, or 16 bits.  Say you store 43690, it would
look like this:

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
15