::::::::: :::::::: ::::::::: :::::::::: :+: :+: :+: :+: :+: :+: :+: +:+ +:+ +:+ +:+ +:+ +:+ +#++:++#+ +#++:++#++ +#++:++#: :#::+::# +#+ +#+ +#+ +#+ +#+ +#+ #+# #+# #+# #+# #+# #+# #+# ######### ######## ### ### ### 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 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