Nytro Posted March 15, 2013 Report Posted March 15, 2013 x86 Assembly for Userland Applications: A Hands-On Approach1. Introduction2. What is Assembly?3. What is the Purpose of Learning Assembly?4. Getting to know the x86 Architecture5. Bits, Bytes and Numbers6. Bit Operations7. Signed Integers8. The First Steps9. Writing Windows Applications Using x86 32-bit Assembly9.1 MASM9.2 FASM9.3 NASM[*]10. Writing Linux/BSD Applications Using x86 32-bit Assembly[*]10.1 as[*]11. Partial Registers[*]12. Addresses[*]13. Control Structures[*]14. Multiplication and Division of Integers[*]15. Floating Point Operations[h=1]Introduction[/h] This document is an introduction to creating programs for microprocessors of the x86 architecture family - in particular 32-bit code. The reader is expected to be familiar with programming in C/C++ (or similar languages such as Java at least) and the essential API of the operating system they are using. Some mathematical knowledge up to highschool/university level is essential for understanding a lot of things aswell. I will try not to be too OS specific but the environments I am going to focus on in this document are Windows, Linux and BSD. Pure knowledge of assembly in itself is useless if you do not know how to combine it with the API of the operating system you are going to run it on so I want to make sure that this will be demonstrated to a certain extent. It is not that different from the way you would do it in a high level programming language such as C++ so it is not difficult to understand. [h=1]What is Assembly?[/h] Assembly (short ASM) is the lowest level programming possible - if you are a programmer and you want to get as close to the hardware as you can get then this is the place you want to be. In assembly code you get to control every single instruction that your CPU (central processing unit) is going to execute. There are different assembly languages for different microprocessor architectures and all of them are different from each other. Usually they are totally incompatible so you will have to write assembly code that is specific to the particular architecture you want your program to run on. In assembly you write instructions using the ASCII character set which directly represent machine code instructions that are executed by your processor. The names of these instructions are usually extremely short and are often abbreviations of full names. These assembly instruction names are called mnemonics. Before your microprocessor can actually run the program you have written in assembly you will have to run it through a program which translates all the mnemonics and arguments to numerical machine code. This program is called an assembler. Assemblers often also support more features than just the pure instructions to make the jobs easier for the programmers but you will see how they do that later on. [h=1]What is the Purpose of Learning Assembly?[/h] This is a very important question and subject to a lot of discussion. My answer to this question is a list of reasons, really. Better understanding of what goes on at the lowest level can make you a better programmer at a higher level. It allows you to see what goes on behind the scenes and it often gives you a totally new perspective on things. It has its uses in writing high performance parts of high level language programming where you need to use features of your processor that are not easily accessible in that high level language. Knowing assembly is obviously also necessary to be able to write compilers for a particular microprocessor architecture which convert high level language code to machine instructions. The truth is that most people learn x86 ASM nowadays to crack commercial software, to reverse engineer closed source programs and to write cheats for computer games. Cracking is the one that made me learn it but I have to admit that I never got particularly good at it and I got totally distracted from my original goal in the process of understanding how it works. It is my experience that it is essential to learn how to write x86 ASM yourself first in order to be successful at cracking and reverse engineering. Knowing how to manually translate a C++ program to assembly is a valuable skill to have for this purpose. [h=1]Getting to know the x86 Architecture[/h] So, what are we dealing with here? The IA-32 microprocessor is basically a register machine which uses a CISC (complex instruction set computer) instruction set. At first I am going to explain what a register machine is. After that I will move on to the CISC part. A register machine is a computing device which stores results of arithmetic operations and such primarily in so called registers. These are small but highly efficient binary storage units inside the processor which can hold integer values. When you are doing assembly programming you deal with them all the time. They are incapable of holding a lot of data at once but they are essential as temporary placeholders used in most instructions executed by the processor. In the terms of the memory hierarchy of contemporary computers they are at the very top. The hierarchy looks like this:CPU registersCPU cacheRAM (random access memory)HDD (hard disk drive storage)External storage, even optical media like CDs, DVDs, BluRay disks and such Registers hold minimal amounts of data and are extremely fast. The cache holds far larger amounts of data but it is still pretty fast. The RAM holds even larger amounts of data and it is far slower (in terms of both bandwidth and latency) than any memory operation inside a CPU. Hard disks have an even larger capacity than your RAM and they are very slow in comparison to the objects at the top of the hierarchy. At this point I should probably briefly explain what the CPU cache actually is. It is a small high performance storage unit inside your CPU to which chunks of memory from the RAM are copied whenever you perform memory accesses. This way the CPU does not have to access the RAM over and over again when it is processing the same piece of data. This speeds up the execution of code a lot - RAM access is vey slow in comparison to cache access after all. In reality this cache is actually not a single unit but it is divided into multiple cache levels. The Level 1 Cache is the smallest but fastest one. The next level is bigger but slower and so on. Caching is not of much interest to somebody who is new to assembly, though. I might cover this topic later in sections with deal with optimising code for speed. Let us get back to the CISC part I mentioned earlier. There are two major microprocessor architecture philosophies known as RISC (reduced instruction set computing) and CISC (complex instruction set computing). In RISC architectures instructions are rather simple and perform very fundamental operations. RISC instructions are incapable of performing multiple actions at once but they are very fast. The instruction format for RISC architectures is usually quite uniform and each instruction takes up the same number of bytes in memory. This makes them very easy to decode for the processor. CISC architectures generally feature complex instructions which perform multiple tasks sequentially, like loading a value from memory, peforming an arithmetic operation on it and then writing the result of the operation into memory. In a RISC architecture this would be divided into multiple instructions. CISC instructions are usually of variable length and they are very complicated to decode for the CPU.Tutorial complet, merita citit:http://siyobik.info.gf/main/documents/view/x86-tutorial/ Quote