[Home]  [Edit this page]  [Recent Changes]  [Special Pages]  [Help
x86ASMFAQ_Basic
I know nothing! Help!

Then you may want to check out x86ASMFAQ_General and x86ASMFAQ_Resource. However, this is a quick overview of the very basics of x86 Assembly, that will (hopefully) give you at least the terminology to understand the rest of the FAQ.

The x86 is a register machine. Some of the general purpose registers the 80386 has are eax, ebx, ecx, and edx. Each of those can be split into the lowest byte, the next highest byte, and the lowest word, denoted as al, ah, and ax, for the register eax. al and ah are 8-bit, ax is 16-bit and al and ah refer to the low and high byte of ax (so changing ax changes al and ah and vice versa) and eax is 32-bit, with ax refering to the lowest 16-bits. The same thing can be done with ebx, ecx and edx.

The instructions of the processor are called opcodes, and the parameters of those opcodes are operands. For example, mov eax, ebx, mov is the opcode and eax and ebx are operands. In this case they are register operands. Another possibility is an ''immediate'' operand, which is a constant, e.g mov eax, 5, 5 is an immediate operand. The final possibility is a memory operand. This is when the value is read from memory and is almost always denoted by putting braces around the address, e.g. mov eax, [5], moves the value at address 5.

How do I make control structures in assembly?

Assembly has no if statements, or while loops. All control structures in assembly need to be created using the equivalent of a conditional goto, or conditional jump. Some templates for common control structures follow...

;if Condition then ThenBody else ElseBody
    test condition
    jmp if not true to else
    ThenBody
    jmp done
else:
    ElseBody
done:
;while Condition do WhileBody
while_test:
    test condition
    jmp if not true to done
    WhileBody
    jmp while_test
done:
;for X = Start to End do ForBody
    mov X, Start
for_test:
    cmp X, End
    jl (or jle, or jb, or jbe) done
    ForBody
    increment X
    jmp for_test
done:


There are other forms of these control structures that may be more appropriate (or more efficient) in other situations.

How do I make an array in assembly? multidimensional?

An array in assembly is simply a contiguous block of memory. To access a specific element in an array you would calculate the offset from the address of the beginning of the array. Typically, you would use the indexed address mode to accomplish this. To get the Nth WORD (two bytes) of an array would look something like...

    mov ax, [start_of_array+N*size_of_word]
;for example (the 5th WORD of array)
    mov ax, [array+5*2]


This is different from C, in that you must handle multiplying by the size of the element yourself, as memory is always access with byte granularity.

A multidimensional array in assembly is just a single dimensional array where you use a different formula to calculate the index. The formula for a two dimensional array would be (row*size_of_row+col)*size_of_element, for a three dimensional array (depth*size_of_depth+row)*size_of_row+col)*size_of_element, and the pattern continues to higher dimensions.

How do I make a string in assembly?

A string in assembly is usually represented as an single dimensional array of bytes. There are two common ways of specifying the size of a string. The most common is C-style. This uses the NUL ASCII code (0) to delimit the end of the string. So "Hi" would be 'H','i',0. The other technique is Pascal-style strings which store the size of the string in the first byte. So "Hi" would be 2,'H',i'. There are variations on these styles that are better in certain situations. Just as a warning, DOS's Print String functions actually uses a '$' instead of NUL (0) to delimit the end of a string, no one knows why...

What is the stack? How does it work?

The x86 processor contains a hardware stack. In general, a stack is a LIFO structure. You push elements onto a stack and pop off the last element you pushed.

The x86 implements the stack via a stack pointer, (e)sp, and a stack segment, ss. It also has two opcodes specifically for the stack, named surprisingly enough, push and pop. Push subtracts two or four to (e)sp, depending on whether you push a word or dword, then stores the value you pushed at [ss:(e)sp]. Pop reads the value at [ss:(e)sp] and then adds two or four to the (e)sp. One thing you should notice about this is that the stack therefore grows downward.

The stack is commonly used to temporarily save the values of registers, for example

    mov eax, 5  ;eax=5
    push eax    ;save eax
    mov eax, 10 ;eax=10
    pop eax     ;eax==5


The stack is also the most common place to pass parameters to functions and it is always implicitly used for function calls and returns.

How do I make a function in assembly?

To create a function in assembly is very simple. You simply declare a label. However, that's not very helpful. A function is a chunk of code that can be called and will return to the caller once it finishes. To make a function you declare a label to specify where the function starts, then you write the code of the function, then your return via the ret opcode. To use the function you simply use the call opcode.

Example:
set_eax_to_10:
    mov eax, 10
    ret
;using the function
    call set_eax_to_10


Most assemblers have special directives to make it clearer what is a function as opposed to just some label and to allow automatic handling of parameters, saving registers, and local variables.

How does recursion work in assembly?

Recursion works in assembly as it does in any language and doesn't require any special code. Recursion is simply where a function calls itself, and is coded simply by having a call opcode in a function call the function it's in. If you treat a recursive function call as you would any other function call (saving the registers you need and what not) then you won't have any problems that you wouldn't normally have in a high-level language. The main problem to watch out for then is infinite recursion. A stack overflow exception is usually indicative of infinite recursion, though it could occur simply from very deep recursion.

What is a jump/call table?

A jump or call table is a table of places to jump to or call and is mainly used in two situations. One situation is a long list of if statements (or C's switch or BASIC's CASE). In those situations, it's more efficient speed-, space-, and typing-wise to use a table and use the condition as an index into the table, then you use an indirect call or jump. A second situation is where you don't know where you are going to jump to or what you are going to call. The entries in the jump/call table can be changed at runtime allowing different behavior to be chosen at run-time without having to rewrite identical code, which would be messy, inefficient, and not extensible.

The virtual table of an object would be an example of this.

How do I make a struct in assembly?

A structure basically gives a name to an offset value. Assembly's indexed address mode can be used to access elements given the address of the structure and the offset. Beyond that there is no support in assembly language itself for structures, instead the assembler may handle it. Any assembler that allows you to use compile-time equates has enough support to allow you to make your own structure system. This is the approach NASM takes. Many assemblers also have directives to make it simpler to generate these names/offsets.

How do I make an object/class in assembly?

Our own AsmGuru62 has a decent introduction to object-oriented programming in assembly at his site. It's TASM specific, but the general ideas should be fairly understandable. This will grow to cover some of the topics he does not and to be more assembler-independent.

last edited (December 8, 2002) by KDivad Leahcim, Number of views: 6062, Current Rev: 7 (Diff)

[Edit this page]  [Page history]  [What links here]  [Discuss this topic]  [Printer Friendly]  

Members

Username:

Password:


Register
Forgot Password?




Programmers Heaven - for .NET, Java, C/C++ and WEB Developers!
© 1996-2008 Community Networks Ltd. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited. Violators of this policy may be subject to legal action. Please read Terms Of Use and Privacy Statement for more information. Development by Tore Nestenius at .NET Consultant - Synchron Data.