Monday, February 13, 2012

NASM Example 3: Input an array and sort it

; See the first example if you have doubts in the undocumented parts of this example.

section .data
welcome:        db      "Input the size of the array; Input q to quit"
w_len:          equ     $ - welcome
in_msg:         db      0xa, "Enter N: "
im_len:         equ     $ - in_msg
num_msg:        db      "Enter the numbers", 10
nm_len:         equ     $ - num_msg
out_msg:        db      "Sorted array: "
om_len:         equ     $ - out_msg

section .bss
n_str:          resb    4
num_str:        resb    4
num_arr:        resd    64

section .text
        global _start
print:
        push    ebx
        push    eax
        mov     eax,4
        mov     ebx,1
        int     0x80
        pop     eax
        pop     ebx
        ret

scan:
        push    ebx
        push    eax
        mov     eax,3
        mov     ebx,0
        int     0x80
        pop     eax
        pop     ebx
        ret

xTen:
        push    ebx
        mov     ebx,eax
        shl     eax,2
        add     eax,ebx
        shl     eax,1
        pop     ebx
        ret

byTen:
        push    edx
        push    ecx
        mov     edx,0
        mov     ecx,10
        div     ecx
        mov     ebx,edx
        pop     ecx
        pop     edx
        ret

toInt:
        push    ebx
        mov     eax,0
        mov     ebx,0
    .loopStr:
        call    xTen
        push    edx
        mov     edx,0
        mov     dl,byte[ecx+ebx]
        sub     dl,0x30
        add     eax,edx
        pop     edx
        inc     ebx
        cmp     byte[ecx+ebx],0xa
        jle     .return
        cmp     ebx,edx
        jge     .return
        jmp     .loopStr
    .return:
        pop     ebx
        ret

toStr:
        push    ebx
        push    eax
        mov     ebx,0
        push    0
    .loopDiv:
        call    byTen
        add     ebx,0x30
        push    ebx
        cmp     eax,0
        jg      .loopDiv
        mov     ebx,0
    .loopStr:
        pop     eax
        cmp     eax,0
        je      .loopFill
        cmp     ebx,edx
        je      .loopStr
        mov     byte[ecx+ebx],al
        inc     ebx
        jmp     .loopStr
    .loopFill:
        cmp     ebx,edx
        je      .return
        mov     byte[ecx+ebx],0
        inc     ebx
        jmp     .loopFill
    .return:
        pop     eax
        pop     ebx
        ret

sortN:  ;ebx=address of the array of numbers, ecx=array size(>0)
        ;Array gets sorted descending order.
        ;Equivalent C program (a = array; n = length):
        ; i=n;
        ; do {
        ;     i--;
        ;     j=i;
        ;     do {
        ;         j--;
        ;         if (a[i]>a[j])
        ;             swap(a[i],s[j]);
        ;     } while(j>0);
        ; } while (i>1);
        push    eax
        push    esi ;esi and edi are used here like eax, ebx etc.; Nothing special!
        push    edi
        mov     edi,ecx
        shl     edi,2
    .loopN:
        sub     edi,4
        mov     eax,dword[ebx+edi]
        mov     esi,edi
    .loopIn:
        sub     esi,4
        cmp     eax,dword[ebx+esi]
        jg      .swap
        jmp     .continue
    .swap:
        push    dword[ebx+esi]
        push    dword[ebx+edi]
        pop     dword[ebx+esi]
        pop     dword[ebx+edi]
        mov     eax,dword[ebx+edi]
    .continue:
        cmp     esi,0
        jg      .loopIn
        cmp     edi,4
        jg      .loopN

        pop     edi
        pop     esi
        pop     eax
        ret

_start:
        mov     ecx,welcome
        mov     edx,w_len
        call    print
    .main_loop:
        mov     ecx,in_msg ;Ask the user for N
        mov     edx,im_len
        call    print

        mov     ecx,n_str ;Input N
        mov     edx,4
        call    scan

        cmp     byte[n_str],0x71 ;If 'q', quit
        je      .quit

        call    toInt ;get the integer N, push it, and move it to ebx
        push    eax
        mov     ebx,eax

        mov     ecx,num_msg ;Ask the user to input all numbers
        mov     edx,nm_len
        call    print

    .loopN_1: ;Input the numbers
        dec     ebx
        ;get the number and store it in [num_arr+ebx*4]
        mov     ecx,num_str
        mov     edx,4
        call    scan
        call    toInt
        mov     edx,ebx
        shl     edx,2 ;edx = edx*4
        mov     dword[num_arr+edx], eax
        cmp     ebx,0
        jne     .loopN_1 ;Note: The numbers will be stored in reverse order of input

        mov     ebx,num_arr
        pop     ecx ;pop N to ecx
        call    sortN
        mov     ebx,ecx

        mov     ecx,out_msg
        mov     edx,om_len
        call    print

    .loopN_2: ;Output the numbers
        dec     ebx
        mov     edx,ebx
        shl     edx,2
        mov     eax, dword[num_arr+edx]
        mov     ecx,num_str
        mov     edx,4
        call    toStr
        mov     byte[num_str+3],0x20 ;ascii code for space
        call    print
        cmp     ebx,0
        jne     .loopN_2 ;Note: The numbers will be printed in reverse order too

        jmp     .main_loop

    .quit:
        mov     ebx,0
        mov     eax,1
        int     0x80


NASM Example 2: Input an array and search for an element

; See the first example if you have doubts in the undocumented parts of this example.

section .data
welcome:        db      "Input the size of the array; Input q to quit"
w_len:          equ     $ - welcome
in_msg:         db      0xa, "Enter N: "
im_len:         equ     $ - in_msg
num_msg:        db      "Enter the numbers", 0xa
nm_len:         equ     $ - num_msg
srch_msg:       db      "Enter the number to search: "
sm_len:         equ     $ - srch_msg
out_msg0:       db      "Number was not found!"
om0_len:        equ     $ - out_msg0
out_msg1:       db      "Number was found at ",0,0,0,0 ;these last 4 bytes will be used to store the index
om1_len:        equ     $ - out_msg1

section .bss
n_str:          resb    4
num_str:        resb    4
num_arr:        resd    64

section .text
        global _start
print:
        push    ebx
        push    eax
        mov     eax,4
        mov     ebx,1
        int     0x80
        pop     eax
        pop     ebx
        ret

scan:
        push    ebx
        push    eax
        mov     eax,3
        mov     ebx,0
        int     0x80
        pop     eax
        pop     ebx
        ret

xTen:
        push    ebx
        mov     ebx,eax
        shl     eax,2
        add     eax,ebx
        shl     eax,1
        pop     ebx
        ret

byTen:
        push    edx
        push    ecx
        mov     edx,0
        mov     ecx,10
        div     ecx
        mov     ebx,edx
        pop     ecx
        pop     edx
        ret

toInt:
        push    ebx
        mov     eax,0
        mov     ebx,0
    .loopStr:
        call    xTen
        push    edx
        mov     edx,0
        mov     dl,byte[ecx+ebx]
        sub     dl,0x30
        add     eax,edx
        pop     edx
        inc     ebx
        cmp     byte[ecx+ebx],0xa
        jle     .return
        cmp     ebx,edx
        jge     .return
        jmp     .loopStr
    .return:
        pop     ebx
        ret

toStr:
        push    ebx
        push    eax
        mov     ebx,0
        push    0
    .loopDiv:
        call    byTen
        add     ebx,0x30
        push    ebx
        cmp     eax,0
        jg      .loopDiv
        mov     ebx,0
    .loopStr:
        pop     eax
        cmp     eax,0
        je      .loopFill
        cmp     ebx,edx
        je      .loopStr
        mov     byte[ecx+ebx],al
        inc     ebx
        jmp     .loopStr
    .loopFill:
        cmp     ebx,edx
        je      .return
        mov     byte[ecx+ebx],0
        inc     ebx
        jmp     .loopFill
    .return:
        pop     eax
        pop     ebx
        ret

searchN:        ;eax=number to be searched, ebx=address of num_arr, ecx=arr_size(>0)
                ;Result: ecx=index of the find (-1 => not found)
        push    edx
    .loopN:
        dec     ecx
        mov     edx,ecx
        shl     edx,2
        cmp     eax,dword[ebx+edx]
        je      .found
        cmp     ecx,0
        jne     .loopN
        mov     ecx,-1

    .found:
        pop     edx
        ret

_start:
        mov     ecx,welcome
        mov     edx,w_len
        call    print
    .main_loop:
        mov     ecx,in_msg ;Ask the user for N
        mov     edx,im_len
        call    print

        mov     ecx,n_str ;Input N
        mov     edx,4
        call    scan

        cmp     byte[n_str],0x71 ;If 'q', quit
        je      .quit

        call    toInt ;get the integer N, push it, and move it to ebx
        push    eax
        mov     ebx,eax

        mov     ecx,num_msg ;Ask the user to input all numbers
        mov     edx,nm_len
        call    print

    .loopN: ;Input the numbers
        dec     ebx
        mov     ecx,num_str ;get the number and store it in [num_arr+ebx*4]
        mov     edx,4
        call    scan
        call    toInt
        mov     edx,ebx
        shl     edx,2 ;edx = edx*4
        mov     dword[num_arr+edx], eax
        cmp     ebx,0
        jne     .loopN ;Note: The numbers will be stored in reverse order of input

        mov     ecx,srch_msg ;Ask for the number to search
        mov     edx,sm_len
        call    print

        mov     ecx,num_str ;get the number to search
        mov     edx,4
        call    scan
        call    toInt

        mov     ebx,num_arr
        pop     ecx ;pop N to ecx
        push    ecx ;push N
        call    searchN ;search for eax in num_arr
        cmp     ecx,-1
        je      .not_found

        pop     eax ;pop N
        sub     eax,ecx ;eax = N - ecx ;Since the numbers were stored in reverse order
                        ;If inputs are 1,2,3,4,5; numbers={5,4,3,2,1}; searchN(4,numbers) will give 1; We want 5-1 = 4
        mov     ecx,out_msg1 ;last 4 bytes of out_msg1 = toStr(eax)
        add     ecx,om1_len
        sub     ecx,4
        mov     edx,4
        call    toStr
        mov     ecx,out_msg1 ;print the whole out_msg1
        mov     edx,om1_len
        call    print
        jmp     .main_loop

    .not_found:
        mov     ecx,out_msg0
        mov     edx,om0_len
        call    print
        jmp     .main_loop

    .quit:
        mov     ebx,0
        mov     eax,1
        int     0x80

Friday, February 10, 2012

Quicksorting in C++

#include <iostream>
#include <fstream>
using namespace std;
void swap(int *a, int i, int j) {
    int t;
    if (i!=j) {
        t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}

int partition(int *arr, int left, int right) {
    int i, j;
    int pivot = (left + right) / 2;
    swap(arr, pivot, right);
    for (i=j=left; i<right; i++) {
        if (arr[i]<arr[right]) {
            swap(arr, i, j);
            j++;
        }
    }
    swap(arr,j,right);
    return j;
}

void quickSort(int *arr, int left, int right) {
      int pivot = partition(arr, left, right);

      if (left < pivot-1)
            quickSort(arr, left, pivot-1);
      if (pivot+1 < right)
            quickSort(arr, pivot+1, right);
}

int main() {
    int a[100], n, i;
    ifstream num_file;
    num_file.open("numbers.txt");
    if (num_file.is_open())
    {
        n=0;
        while (!num_file.eof())
            num_file >> a[n++];
        //n--;
        num_file.close();
        cout << "Given array: ";
        for (i=0; i<n; i++)
            cout << a[i] << " ";
        quickSort(a, 0, n-1);
        cout << "\nSorted array: ";
        for (i=0; i<n; i++)
            cout << a[i] << " ";
        cout << endl;
    } else
        cout << "Error opening file!";
    return 0;
}

Sunday, February 5, 2012

NASM Example 1: Sum of first N natural numbers

;See NASM Documentation for reference.
;Note that this whole code is assembled and loaded into the memory (RAM) during execution.
;Every data and instruction has an address associated with it.

section .data   ;initialised data section
                ;db means 'define bytes' (There are dw, dd, dq; w = word = 2 bytes; d = double word; q = quad word)
                ;db,dw,dd,dq are pseudo-instructions which associates the address of the given data with the label
welcome:        db      "Input a number between 1 and 999; Input q to quit"
                ;equ evaluates its operand '$ - welcome' once and associates its value with the label (no addresses involved)
w_len:          equ     $ - welcome ;Reads: 'dollar minus welcome'
                                    ;'$' evaluates to the assembled position at the beginning of that line.
                                    ;'welcome' is the address of the first byte of that string
in_msg:         db      0xa, "Enter n: "        ;0xa = hexadecimal equivalent of 10 = the ascii code of line-break
im_len:         equ     $ - in_msg
out_msg:        db      "Sum: "
om_len:         equ     $ - out_msg

section .bss    ;uninitialised data section
                ;resb means 'reserve bytes' (There are also resw, resd, resq like before)
n_str:          resb    4       ;reserves 4 bytes and associates the address of the first byte with n_str
sum_str:        resb    7

section .text
                        ;we must export the entry point to the ELF linker (ld). [Executable and Linkable Format]
        global _start   ;'ld' conventionally recognize _start as their entry point.
                        ;Use `ld -e entry_point` to override the default.

                        ;RgsA =:means:= Registers Afftected

print:                  ;In:    ecx=address of the string
                        ;       edx=length of string
                        ;RgsA:  none
        push    ebx     ;push the value of ebx into the stack (Stack Pointer, esp = esp-4)
        push    eax
        mov     eax,4   ;4 is the syscall code for write
        mov     ebx,1   ;std output (terminal)
        int     0x80    ;syscall (kernel interrupt)
        pop     eax     ;loads the (last pushed) value from the stack into eax (esp = esp+4)
        pop     ebx
        ret             ;ret and call are explained later...

scan:                   ;In:    ecx=address where the input gets stored
                        ;       edx=max length of input string
                        ;RgsA:  none
        push    ebx
        push    eax
        mov     eax,3   ;syscall code for read
        mov     ebx,0   ;std input (terminal)
        int     0x80
        pop     eax
        pop     ebx
        ret

xTen:                   ;Result: eax=eax*10
                        ;RgsA: eax
        push    ebx
        mov     ebx,eax ;ebx=eax
        shl     eax,2   ;shift left by 2 places
        add     eax,ebx ;eax=eax+ebx
        shl     eax,1
        pop     ebx
        ret

byTen:                  ;Result: eax=eax/10, ebx=eax%10
                        ;RgsA:   eax, ebx
        push    edx
        push    ecx
        mov     edx,0
        mov     ecx,10
        div     ecx
        mov     ebx,edx
        pop     ecx
        pop     edx
        ret

toInt:                  ;Out:   eax=toInt(string at ecx)
                        ;In:    ecx=address of string
                        ;       edx=max length of string
                        ;RgsA:  eax
        push    ebx
        mov     eax,0
        mov     ebx,0
    .loopStr:           ;'.label' means local label. It is associated with the previous non-local label
        call    xTen    ;So this '.loopStr' can be globally accessed as 'toInt.loopStr' (rarely needed)
        push    edx     ;store edx
        mov     edx,0
        mov     dl,byte[ecx+ebx]        ;[..] means dereferencing, 'byte' tells the size of dereferenced data
                                        ; there are also word, dword and qword
        sub     dl,0x30 ;ascii code of '0'
        add     eax,edx
        pop     edx     ;restore edx
        inc     ebx     ;increment ebx by 1
        cmp     byte[ecx+ebx],0xa
        jle     .return
        cmp     ebx,edx
        jge     .return
        jmp     .loopStr
    .return:
        pop     ebx
        ret

toStr:                  ;Out:   ecx=toStr(eax)
                        ;In:    eax=integer to convert
                        ;       ecx=address where string should be stored 
                        ;       edx=max length of string
                        ;RgsA:  none
        push    ebx
        push    eax
        mov     ebx,0
        push    0
    .loopDiv:                   ;repeatedly divide eax by 10 and stack up the remainders (ascii) till eax=0
        call    byTen
        add     ebx,0x30
        push    ebx
        cmp     eax,0
        jg      .loopDiv
        mov     ebx,0
    .loopStr:                   ;pop the remainders into [ecx+n] (this will be in reverse order to stacking)
        pop     eax
        cmp     eax,0
        je      .loopFill
        cmp     ebx,edx
        je      .loopStr        ;pop the remaining items from the stack if the number cannot fit into the string
        mov     byte[ecx+ebx],al        ;Note that the value of eax, ax and al are the same until
                                        ; they are overflowed (ie. eax=256 [2^8] then al=0, ah=1, ax=2^8)
        inc     ebx
        jmp     .loopStr
    .loopFill:                  ;fill the remaining space in [ecx+..] with zeroes (null values)
        cmp     ebx,edx
        je      .return
        mov     byte[ecx+ebx],0
        inc     ebx
        jmp     .loopFill
    .return:
        pop     eax
        pop     ebx
        ret

sumN:                   ;eax=1+2+3+...+ebx; RgsA: eax
        mov     eax,0
        push    ebx
    .loopN:
        add     eax,ebx
        dec     ebx
        jnz     .loopN
        pop     ebx
        ret

_start:
        mov     ecx,welcome             ;the address of the string is copied to ecx
        mov     edx,w_len               ;the length of the string is copied to edx
        call    print                   ;the current instruction pointer (IP) is pushed into the stack
                                        ; and jumps to the address (instruction) associated with 'print'.
                                        ;Note: IP stores the address of next instruction to be executed.
                                        ;'ret' pops into the IP jumping to the next instruction here.
                                        ;So before 'ret' is executed, all items we pushed after the call
                                        ; statement must be popped so that the current IP itself is popped back.
    .main_loop:
        mov     ecx,in_msg
        mov     edx,im_len
        call    print

        mov     ecx,n_str
        mov     edx,4
        call    scan

        cmp     byte[n_str],0x71        ;ascii code of 'q'
        je      .quit

        call    toInt

        mov     ebx,eax
        call    sumN

        mov     ecx,out_msg
        mov     edx,om_len
        call    print

        mov     ecx,sum_str
        mov     edx,7
        call    toStr

        call    print
        jmp     .main_loop

    .quit:
        mov     ebx,0
        mov     eax,1
        int     0x80

;Compiling and executing:
;    nasm -f elf sum.asm
;    ld -s -o outfile sum.o
;        ;If you are using a 64-bit linux distribution, run instead
;        ;    ld -m elf_i386 -s -o outfile sum.o
;    ./outfile

NASM Docs Index

Contents

!= operator: Section 4.3.3
$ Here token: Section 3.5
$$ token: Section 3.5, Section 6.5.2
% operator: Section 3.5.6
%$ and %$$ prefixes: Section 4.6.2
%% operator: Section 3.5.6, Section 4.2.2
%+1 and %-1 syntax: Section 4.2.8
%0 parameter count: Section 4.2.4, Section 4.2.5
& operator: Section 3.5.3
&& operator: Section 4.3.3
* operator: Section 3.5.6
+ modifier: Section 4.2.3
+ operator, binary: Section 3.5.5
+ operator, unary: Section 3.5.7
- operator, binary: Section 3.5.5
- operator, unary: Section 3.5.7
..@ symbol prefix: Section 3.8, Section 4.2.2
/ operator: Section 3.5.6
// operator: Section 3.5.6
< operator: Section 4.3.3
<< operator: Section 3.5.4
<= operator: Section 4.3.3
<> operator: Section 4.3.3
= operator: Section 4.3.3
== operator: Section 4.3.3
> operator: Section 4.3.3
>= operator: Section 4.3.3
>> operator: Section 3.5.4
? MASM syntax: Section 3.2.2
^ operator: Section 3.5.2
^^ operator: Section 4.3.3
| operator: Section 3.5.1
|| operator: Section 4.3.3
~ operator: Section 3.5.7
-a option: Section 2.1.9
a16: Section 9.3, Section A.19, Section A.80, Section A.98, Section A.105, Section A.112, Section A.126, Section A.134, Section A.149, Section A.157, Section A.169
a32: Section 9.3, Section A.19, Section A.80, Section A.98, Section A.105, Section A.112, Section A.126, Section A.134, Section A.149, Section A.157, Section A.169
a86: Section 1.1.1, Section 2.2, Section 2.2.2, Section 2.2.6
AAA: Section A.4
AAD: Section A.4
AAM: Section A.4
AAS: Section A.4
ABSOLUTE: Section 5.3, Section 6.2.1
ADC: Section A.5
ADD: Section A.6
addition: Section 3.5.5
addressing, mixed-size: Section 9.2
address-size prefixes: Section 3.1
algebra: Section 3.3
ALIGN: Section 4.7.5, Section 6.1.2, Section 6.2.1
ALIGNB: Section 4.7.5
alignment, in bin sections: Section 6.1.2
alignment, in elf sections: Section 6.5.1
alignment, in obj sections: Section 6.2.1
alignment, in win32 sections: Section 6.3.1
alignment, of elf common variables: Section 6.5.4
alloc: Section 6.5.1
alt.lang.asm: Section 1.1.1, Section 1.2
ambiguity: Section 2.2.3
AND: Section A.7
a.out, BSD version: Section 6.7
a.out, Linux version: Section 6.6
aout: Section 2.1.1, Section 6.6
aoutb: Section 6.7, Section 8.2
arg: Section 7.4.5, Section 8.1.4
ARPL: Section A.8
as86: Section 1.1.1, Section 2.1.1, Section 6.8
assembler directives: Chapter 5
assembly passes: Section 3.7
assembly-time options: Section 2.1.7
%assign: Section 4.1.2
ASSUME: Section 2.2.4
AT: Section 4.7.4
Autoconf: Section 1.3.2
autoexec.bat: Section 1.3.1
bin: Section 2.1.1, Section 2.1.2, Section 6.1
binary: Section 3.4.1
binary files: Section 3.2.3
16-bit mode, versus 32-bit mode: Section 5.1
bit shift: Section 3.5.4
BITS: Section 5.1, Section 6.1
bitwise AND: Section 3.5.3
bitwise OR: Section 3.5.1
bitwise XOR: Section 3.5.2
block IFs: Section 4.6.5
boot loader: Section 6.1
boot sector: Section 10.1.3
Borland, Pascal: Section 7.5
Borland, Win32 compilers: Section 6.2
BOUND: Section A.9
braces, after % sign: Section 4.2.7
braces, around macro parameters: Section 4.2
BSD: Section 8.2
BSF: Section A.10
BSR: Section A.10
.bss: Section 6.1, Section 6.5.1, Section 6.6, Section 6.7, Section 6.8, Section 6.9
BSWAP: Section A.11
BT: Section A.12
BTC: Section A.12
BTR: Section A.12
BTS: Section A.12
bugs: Section 10.2
BYTE: Section 10.1.1
C calling convention: Section 7.4.3, Section 8.1.2
C symbol names: Section 7.4.1
CALL: Section A.13
CALL FAR: Section 3.6
case sensitivity: Section 2.2.1, Section 4.1.1, Section 4.1.2, Section 4.2, Section 4.3.4, Section 6.2.3
CBW: Section A.14
CDQ: Section A.14
changing sections: Section 5.2
character constant: Section 3.2.1, Section 3.4.2
circular references: Section 4.1.1
CLASS: Section 6.2.1
CLC: Section A.15
CLD: Section A.15
%clear: Section 4.7
CLI: Section A.15
CLTS: Section A.15
c16.mac: Section 7.4.5, Section 7.5.3
c32.mac: Section 8.1.4
CMC: Section A.16
CMOVcc: Section A.17
CMP: Section A.18
CMPSB: Section A.19
CMPSD: Section A.19
CMPSW: Section A.19
CMPXCHG: Section A.20
CMPXCHG486: Section A.20
CMPXCHG8B: Section A.21
coff: Section 2.1.1, Section 6.4
colon: Section 3.1
.COM: Section 6.1, Section 7.2
command-line: Section 2.1, Chapter 6
commas in macro parameters: Section 4.2.3
COMMON: Section 5.6, Section 6.2.1
COMMON, elf extensions to: Section 6.5.4
COMMON, obj extensions to: Section 6.2.8
Common Object File Format: Section 6.4
common variables: Section 5.6
common variables, alignment in elf: Section 6.5.4
common variables, element size: Section 6.2.8
comp.archives.msdos.announce: Section 1.2
comp.lang.asm.x86: Section 1.1.1, Section 1.2
comp.os.linux.announce: Section 1.2
comp.os.msdos.programmer: Section 7.3
concatenating macro parameters: Section 4.2.7
condition codes: Section A.2.2
condition codes as macro parameters: Section 4.2.8
conditional assembly: Section 4.3
conditional jump: Section A.89
conditional jumps: Section 10.1.2
conditional-return macro: Section 4.2.8
configure: Section 1.3.2
constants: Section 3.4
context stack: Section 4.6, Section 4.6.5
context-local labels: Section 4.6.2
context-local single-line macros: Section 4.6.3
control registers: Section A.2.1
counting macro parameters: Section 4.2.5
CPUID: Section 3.4.2, Section A.22
creating contexts: Section 4.6.1
critical expression: Section 3.2.2, Section 3.2.4, Section 3.7, Section 4.1.2, Section 5.3
CWD: Section A.14
CWDE: Section A.14
-d option: Section 2.1.7
DAA: Section A.23
DAS: Section A.23
.data: Section 6.1, Section 6.5.1, Section 6.6, Section 6.7, Section 6.8, Section 6.9
_DATA: Section 7.4.2
data: Section 6.5.3
data structure: Section 7.4.4, Section 8.1.3
DB: Section 3.2, Section 3.2.1, Section 3.4.3
dbg: Section 6.10
DD: Section 3.2, Section 3.2.1, Section 3.4.3, Section 3.4.4
debug registers: Section A.2.1
DEC: Section A.24
declaring structures: Section 4.7.3
default macro parameters: Section 4.2.4
default name: Chapter 6
default-WRT mechanism: Section 6.2.7
%define: Section 2.1.7, Section 4.1.1
defining sections: Section 5.2
design goals: Section 2.2.2
DevPac: Section 3.2.3, Section 3.8
disabling listing expansion: Section 4.2.9
DIV: Section A.25
division: Section 3.5.6
DJGPP: Section 6.4, Chapter 8
djlink: Section 7.1.1
DLL symbols, exporting: Section 6.2.5
DLL symbols, importing: Section 6.2.4
DOS: Section 1.3.1, Section 2.1.4
DOS archive: Section 1.3.1
DOS source archive: Section 1.3.1
DQ: Section 3.2, Section 3.2.1, Section 3.4.3, Section 3.4.4
.drectve: Section 6.3.1
DT: Section 3.2, Section 3.2.1, Section 3.4.3, Section 3.4.4
DUP: Section 2.2.7, Section 3.2.5
DW: Section 3.2, Section 3.2.1, Section 3.4.3
DWORD: Section 3.1
-e option: Section 2.1.8
effective addresses: Section 3.1, Section 3.3, Section 3.7, Section A.2.3
element size, in common variables: Section 6.2.8
elf: Section 2.1.1, Section 6.5
elf shared libraries: Section 6.5.2
%elif: Section 4.3, Section 4.3.3
%elifctx: Section 4.3.2
%elifdef: Section 4.3.1
%elifid: Section 4.3.5
%elifidn: Section 4.3.4
%elifidni: Section 4.3.4
%elifnctx: Section 4.3.2
%elifndef: Section 4.3.1
%elifnid: Section 4.3.5
%elifnidn: Section 4.3.4
%elifnidni: Section 4.3.4
%elifnnum: Section 4.3.5
%elifnstr: Section 4.3.5
%elifnum: Section 4.3.5
%elifstr: Section 4.3.5
%else: Section 4.3
e-mail: Section 1.2
EMMS: Section A.26
endproc: Section 7.4.5, Section 8.1.4
%endrep: Section 4.4
ENDSTRUC: Section 4.7.3, Section 5.3
ENTER: Section A.27
environment: Section 2.1.11
EQU: Section 3.2, Section 3.2.4, Section 3.7
%error: Section 4.3.6
error messages: Section 2.1.4
EVEN: Section 4.7.5
.EXE: Section 6.2, Section 7.1
EXE_begin: Section 7.1.2
EXE2BIN: Section 7.2.2
exebin.mac: Section 7.1.2
exec: Section 6.5.1
executable and linkable format: Section 6.5
EXE_end: Section 7.1.2
EXE_stack: Section 7.1.2
%exitrep: Section 4.4
EXPORT: Section 6.2.5
exporting symbols: Section 5.5
expressions: Section 2.1.8, Section 3.5
extension: Section 2.1.1, Chapter 6
EXTERN: Section 5.4
extern, obj extensions to: Section 6.2.7
-f option: Section 2.1.2, Chapter 6
FABS: Section A.29
FADD: Section A.30
FADDP: Section A.30
far call: Section 2.2.5, Section A.13
far common variables: Section 6.2.8
far jump: Section A.88
far pointer: Section 3.6
FARCODE: Section 7.4.5, Section 7.5.3
FBLD: Section A.31
FBSTP: Section A.31
FCHS: Section A.32
FCLEX: Section A.33
FCMOVcc: Section A.34
FCOM: Section A.35
FCOMI: Section A.35
FCOMIP: Section A.35
FCOMP: Section A.35
FCOMPP: Section A.35
FCOS: Section A.36
FDECSTP: Section A.37
FDIV: Section A.39
FDIVP: Section A.39
FDIVR: Section A.39
FDIVRP: Section A.39
FFREE: Section A.40
FIADD: Section A.41
FICOM: Section A.42
FICOMP: Section A.42
FIDIV: Section A.43
FIDIVR: Section A.43
FILD: Section A.44
__FILE__: Section 4.7.2
FIMUL: Section A.45
FINCSTP: Section A.46
FINIT: Section A.47
FIST: Section A.44
FISTP: Section A.44
FISUB: Section A.48
FLAT: Section 6.2.1
flat memory model: Chapter 8
flat-form binary: Section 6.1
FLD: Section A.49
FLDCW: Section A.51
FLDENV: Section A.52
FLDxx: Section A.50
floating-point: Section 2.2.6, Section 3.1, Section 3.2.1, Section 3.4.4
floating-point, constants: Section 3.4.4
floating-point, registers: Section A.2.1
FMUL: Section A.53
FMULP: Section A.53
FNINIT: Section A.47
FNOP: Section A.54
format-specific directives: Chapter 5
forward references: Section 3.7
FPATAN: Section A.55
FPREM: Section A.56
FPREM1: Section A.56
FPTAN: Section A.55
frame pointer: Section 7.4.3, Section 7.5.1, Section 8.1.2
FreeBSD: Section 6.7, Section 8.2
FreeLink: Section 7.1.1
FRNDINT: Section A.57
FRSTOR: Section A.58
FSAVE: Section A.58
FSCALE: Section A.59
FSETPM: Section A.60
FSIN: Section A.61
FSINCOS: Section A.61
FSQRT: Section A.62
FST: Section A.63
FSTCW: Section A.64
FSTENV: Section A.65
FSTP: Section A.63
FSTSW: Section A.66
FSUB: Section A.67
FSUBP: Section A.67
FSUBR: Section A.67
FSUBRP: Section A.67
ftp.coast.net: Section 1.2
ftp.simtel.net: Section 1.2, Section 7.1.1
FTST: Section A.68
FUCOMxx: Section A.69
function: Section 6.5.3
functions, C calling convention: Section 7.4.3, Section 8.1.2
functions, Pascal calling convention: Section 7.5.1
FXAM: Section A.70
FXCH: Section A.71
FxDISI: Section A.38
FxENI: Section A.38
F2XM1: Section A.28
FXTRACT: Section A.72
FYL2X: Section A.73
FYL2XP1: Section A.73
gas: Section 1.1.1
gcc: Section 1.1.1
general purpose register: Section A.1
GLOBAL: Section 5.5
GLOBAL, aoutb extensions to: Section 6.5.3
GLOBAL, elf extensions to: Section 6.5.3
global offset table: Section 8.2
_GLOBAL_OFFSET_TABLE_: Section 6.5.2
..got: Section 6.5.2
GOT relocations: Section 8.2.3
GOT: Section 6.5.2, Section 8.2
..gotoff: Section 6.5.2
GOTOFF relocations: Section 8.2.2
..gotpc: Section 6.5.2
GOTPC relocations: Section 8.2.1
graphics: Section 3.2.3
greedy macro parameters: Section 4.2.3
GROUP: Section 6.2.2
groups: Section 3.6
hex: Section 3.4.1
HLT: Section A.74
hybrid syntaxes: Section 2.2.2
-i option: Section 2.1.5
%iassign: Section 4.1.2
IBTS: Section A.75
ICEBP: Section A.82
%idefine: Section 4.1.1
IDIV: Section A.76
IEND: Section 4.7.4
%if: Section 4.3, Section 4.3.3
%ifctx: Section 4.3.2, Section 4.6.5
%ifdef: Section 4.3.1
%ifid: Section 4.3.5
%ifidn: Section 4.3.4
%ifidni: Section 4.3.4
%ifnctx: Section 4.3.2
%ifndef: Section 4.3.1
%ifnid: Section 4.3.5
%ifnidn: Section 4.3.4
%ifnidni: Section 4.3.4
%ifnnum: Section 4.3.5
%ifnstr: Section 4.3.5
%ifnum: Section 4.3.5
%ifstr: Section 4.3.5
%imacro: Section 4.2
immediate operand: Section A.1
IMPORT: Section 6.2.4
import library: Section 6.2.4
importing symbols: Section 5.4
IMUL: Section A.77
IN: Section A.78
INC: Section A.79
INCBIN: Section 3.2, Section 3.2.3, Section 3.4.3
%include: Section 2.1.5, Section 2.1.6, Section 4.5
include search path: Section 2.1.5
including other files: Section 4.5
inefficient code: Section 10.1.1
infinite loop: Section 3.5
informational section: Section 6.3.1
INSB: Section A.80
INSD: Section A.80
INSTALL: Section 1.3.2
installing: Section 1.3.1
instances of structures: Section 4.7.4
INSW: Section A.80
INT: Section A.81
INT01: Section A.82
INT1: Section A.82
INT3: Section A.82
integer overflow: Section 3.5
intel number formats: Section 3.4.4
INTO: Section A.83
INVD: Section A.84
INVLPG: Section A.85
IRET: Section A.86
IRETD: Section A.86
IRETW: Section A.86
ISTRUC: Section 4.7.4
iterating over macro parameters: Section 4.2.6
Jcc: Section A.89
Jcc NEAR: Section 10.1.2
JCXZ: Section A.87
JECXZ: Section A.87
JMP: Section A.88
JMP DWORD: Section 9.1
jumps, mixed-size: Section 9.1
-l option: Section 2.1.3
label prefix: Section 3.8
LAHF: Section A.90
LAR: Section A.91
ld86: Section 6.8
LDS: Section A.92
LEA: Section A.93
LEAVE: Section A.94
LES: Section A.92
LFS: Section A.92
LGDT: Section A.95
LGS: Section A.92
LIBRARY: Section 6.9.1
licence: Section 1.1.2
LIDT: Section A.95
__LINE__: Section 4.7.2
linker, free: Section 7.1.1
Linux ELF: Section 6.5
listing file: Section 2.1.3
little-endian: Section 3.4.2
LLDT: Section A.95
LMSW: Section A.96
LOADALL: Section A.97
LOADALL286: Section A.97
local labels: Section 3.8
LODSB: Section A.98
LODSD: Section A.98
LODSW: Section A.98
logical AND: Section 4.3.3
logical OR: Section 4.3.3
logical XOR: Section 4.3.3
LOOP: Section A.99
LOOPE: Section A.99
LOOPNE: Section A.99
LOOPNZ: Section A.99
LOOPZ: Section A.99
LSL: Section A.100
LSS: Section A.92
LTR: Section A.101
%macro: Section 4.2
macro library: Section 2.1.5
macro processor: Chapter 4
macro-local labels: Section 4.2.2
macro-params: Section 2.1.10
macros: Section 3.2.5
make: Section 1.3.2
makefiles: Section 1.3.1, Section 1.3.2
Makefile.unx: Section 1.3.2
man pages: Section 1.3.2
MASM: Section 1.1.1, Section 2.2, Section 3.2.5, Section 6.2
memory models: Section 2.2.5, Section 7.4.2
memory operand: Section 3.1
memory references: Section 2.2.2, Section 3.3, Section A.1
Microsoft OMF: Section 6.2
misc subdirectory: Section 7.1.2, Section 7.4.5, Section 8.1.4
mixed-language program: Section 7.4
mixed-size addressing: Section 9.2
mixed-size instruction: Section 9.1
MMX registers: Section A.2.1
ModR/M byte: Section A.2, Section A.2.3
modulo operators: Section 3.5.6
MOV: Section A.102
MOVD: Section A.103
MOVQ: Section A.104
MOVSB: Section A.105
MOVSD: Section A.105
MOVSW: Section A.105
MOVSX: Section A.106
MOVZX: Section A.106
MS-DOS: Section 6.1
MS-DOS device drivers: Section 7.3
MUL: Section A.107
multi-line macros: Section 2.1.10, Section 4.2
multiplication: Section 3.5.6
multipush macro: Section 4.2.6
nasm.1: Section 1.3.2
NASM version: Section 4.7.1
__NASMDEFSEG: Section 6.2
nasm.exe: Section 1.3.1
nasm -h: Section 2.1.2
__NASM_MAJOR__: Section 4.7.1
__NASM_MINOR__: Section 4.7.1
nasm.out: Section 2.1.1
nasmw.exe: Section 1.3.1
nasmXXXs.zip: Section 1.3.1
nasm-X.XX.tar.gz: Section 1.3.2
nasmXXX.zip: Section 1.3.1
ndisasm.1: Section 1.3.2
ndisasm.exe: Section 1.3.1
ndisasmw.exe: Section 1.3.1
near call: Section 2.2.5, Section A.13
near common variables: Section 6.2.8
near jump: Section A.88
NEG: Section A.108
NetBSD: Section 6.7, Section 8.2
new releases: Section 1.2
noalloc: Section 6.5.1
nobits: Section 6.5.1
noexec: Section 6.5.1
.nolist: Section 4.2.9
NOP: Section A.109
NOT: Section A.108
`nowait': Section 2.2.6
nowrite: Section 6.5.1
number-overflow: Section 2.1.10
numeric constants: Section 3.2.1, Section 3.4.1
-o option: Section 2.1.1
o16: Section 9.3, Section A.126, Section A.134
o32: Section 9.3, Section A.126, Section A.134
.OBJ: Section 7.1
obj: Section 2.1.1, Section 6.2
object: Section 6.5.3
octal: Section 3.4.1
OF_DBG: Section 6.10
OF_DEFAULT: Section 2.1.2
OFFSET: Section 2.2.2
OMF: Section 6.2
omitted parameters: Section 4.2.4
one's complement: Section 3.5.7
OpenBSD: Section 6.7, Section 8.2
operands: Section 3.1
operand-size prefixes: Section 3.1
operating system, writing: Section 9.1
operating system: Section 6.1
operators: Section 3.5
OR: Section A.110
ORG: Section 6.1.1, Section 7.2.1, Section 7.2.2, Section 10.1.3
orphan-labels: Section 2.1.10, Section 3.1
OS/2: Section 6.2, Section 6.2.1
OUT: Section A.111
out of range, jumps: Section 10.1.2
output file format: Section 2.1.2
output formats: Chapter 6
OUTSB: Section A.112
OUTSD: Section A.112
OUTSW: Section A.112
overlapping segments: Section 3.6
OVERLAY: Section 6.2.1
overloading multi-line macros: Section 4.2.1
overloading, single-line macros: Section 4.1.1
-p option: Section 2.1.6, Section 4.5
PACKSSDW: Section A.113
PACKSSWB: Section A.113
PACKUSWB: Section A.113
PADDSIW: Section A.115
PADDxx: Section A.114
PAND: Section A.116
PANDN: Section A.116
paradox: Section 3.7
PASCAL: Section 7.5.3
Pascal calling convention: Section 7.5.1
passes, assembly: Section 3.7
PATH: Section 1.3.1
PAVEB: Section A.117
PCMPxx: Section A.118
PDISTIB: Section A.119
period: Section 3.8
Perl: Section 1.3.1
perverse: Section 2.1.5
PharLap: Section 6.2.1
PIC: Section 6.5.2, Section 6.7, Section 8.2
..plt: Section 6.5.2
PLT relocations: Section 6.5.2, Section 8.2.4, Section 8.2.5
plt relocations: Section 8.2.5
PMACHRIW: Section A.120
PMADDWD: Section A.121
PMAGW: Section A.122
PMULHRIW: Section A.123
PMULHRW: Section A.123
PMULHW: Section A.124
PMULLW: Section A.124
PMVccZB: Section A.125
%pop: Section 4.6, Section 4.6.1
POP: Section A.126
POPAx: Section A.127
POPFx: Section A.128
POR: Section A.129
position-independent code: Section 6.5.2, Section 6.7, Section 8.2
precedence: Section 3.5
pre-defining macros: Section 2.1.7, Section 4.1.1
preferred: Section 3.6
$prefix: Section 3.1, Section 3.4.1
pre-including files: Section 2.1.6
preprocess-only mode: Section 2.1.8
preprocessor: Section 2.1.8, Section 2.1.9, Section 3.2.4, Section 3.5.6, Chapter 4
preprocessor expressions: Section 2.1.8
preprocessor loops: Section 4.4
preprocessor variables: Section 4.1.2
primitive directives: Chapter 5
PRIVATE: Section 6.2.1
proc: Section 7.4.5, Section 8.1.4
procedure linkage table: Section 6.5.2, Section 8.2.4, Section 8.2.5
processor mode: Section 5.1
progbits: Section 6.5.1
program entry point: Section 6.2.6, Section 7.1.1
program origin: Section 6.1.1
pseudo-instructions: Section 3.2
PSLLx: Section A.130
PSRAx: Section A.130
PSRLx: Section A.130
PSUBSIW: Section A.132
PSUBxx: Section A.131
PUBLIC: Section 5.5, Section 6.2.1
PUNPCKxxx: Section A.133
pure binary: Section 6.1
%push: Section 4.6, Section 4.6.1
PUSH: Section A.134
PUSHAx: Section A.135
PUSHFx: Section A.136
PXOR: Section A.137
QBasic: Section 1.3.1
quick start: Section 2.2
QWORD: Section 3.1
RCL: Section A.138
RCR: Section A.138
rdf: Section 2.1.1, Section 6.9
RDMSR: Section A.139
rdoff subdirectory: Section 1.3.2, Section 6.9
RDPMC: Section A.140
RDTSC: Section A.141
redirecting errors: Section 2.1.4
register push: Section A.134
relational operators: Section 4.3.3
Relocatable Dynamic Object File Format: Section 6.9
relocations, PIC-specific: Section 6.5.2
removing contexts: Section 4.6.1
renaming contexts: Section 4.6.4
%rep: Section 3.2.5, Section 4.4
repeating: Section 3.2.5, Section 4.4
%repl: Section 4.6.4
reporting bugs: Section 10.2
RESB: Section 2.2.7, Section 3.2, Section 3.2.2, Section 3.7
RESD: Section 3.2, Section 3.2.2
RESQ: Section 3.2, Section 3.2.2
REST: Section 3.2, Section 3.2.2
restricted memory references: Section A.1
RESW: Section 3.2, Section 3.2.2
RET: Section A.142
RETF: Section A.142
RETN: Section A.142
ROL: Section A.143
ROR: Section A.143
%rotate: Section 4.2.6
rotating macro parameters: Section 4.2.6
RSM: Section A.144
-s option: Section 2.1.4
SAHF: Section A.145
SAL: Section A.146
SALC: Section A.147
SAR: Section A.146
SBB: Section A.148
SCASB: Section A.149
SCASD: Section A.149
SCASW: Section A.149
searching for include files: Section 4.5
__SECT__: Section 5.2.1, Section 5.3
SECTION: Section 5.2
SECTION, elf extensions to: Section 6.5.1
SECTION, win32 extensions to: Section 6.3.1
section alignment, in bin: Section 6.1.2
section alignment, in elf: Section 6.5.1
section alignment, in obj: Section 6.2.1
section alignment, in win32: Section 6.3.1
section, bin extensions to: Section 6.1.2
SEG: Section 3.5.7, Section 3.6, Section 6.2
SEGMENT: Section 5.2
SEGMENT, elf extensions to: Section 6.2.1
segment address: Section 3.5.7, Section 3.6
segment alignment, in bin: Section 6.1.2
segment alignment, in obj: Section 6.2.1
segment names, Borland Pascal: Section 7.5.2
segment override: Section 2.2.4, Section 3.1
segment registers: Section A.2.1
segments: Section 3.6
segments, groups of: Section 6.2.2
separator character: Section 2.1.11
SETcc: Section A.150
SGDT: Section A.151
shared libraries: Section 6.7, Section 8.2
shared library: Section 6.5.3
shift command:
shift command: Section 4.2.6
SHL: Section A.152
SHLD: Section A.153
SHR: Section A.152
SHRD: Section A.153
SIB byte: Section A.2, Section A.2.3
SIDT: Section A.151
signed division: Section 3.5.6
signed modulo: Section 3.5.6
single-line macros: Section 4.1
size, of symbols: Section 6.5.3
SLDT: Section A.151
SMI: Section A.154
SMSW: Section A.155
-soname: Section 8.2.6
sound: Section 3.2.3
source code: Section 1.3.1
source-listing file: Section 2.1.3
square brackets: Section 2.2.2, Section 3.3
STACK: Section 6.2.1
standard macros: Section 4.7
standardised section names: Section 5.2, Section 6.1, Section 6.3.1, Section 6.5.1, Section 6.6, Section 6.7, Section 6.8, Section 6.9
..start: Section 6.2.6, Section 7.1.1
STC: Section A.156
STD: Section A.156
stderr: Section 2.1.4
stdout: Section 2.1.4
STI: Section A.156
STOSB: Section A.157
STOSD: Section A.157
STOSW: Section A.157
STR: Section A.158
string constant: Section 3.2.1
STRUC: Section 4.7.3, Section 5.3, Section 7.4.4, Section 8.1.3
stub preprocessor: Section 2.1.9
SUB: Section A.159
subtraction: Section 3.5.5
sunsite.unc.edu: Section 1.2
suppressible warning: Section 2.1.10
suppressing preprocessing: Section 2.1.9
switching between sections: Section 5.2
..sym: Section 6.5.2
symbol sizes, specifying: Section 6.5.3
symbol types, specifying: Section 6.5.3
symbols, exporting from DLLs: Section 6.2.5
symbols, importing from DLLs: Section 6.2.4
.SYS: Section 6.1, Section 7.3
TASM: Section 1.1.1, Section 2.2, Section 6.2
TBYTE: Section 2.2.7
TEST: Section A.160
test subdirectory: Section 7.1.1
test registers: Section A.2.1
testing arbitrary numeric expressions: Section 4.3.3
testing exact text identity: Section 4.3.4
testing single-line macro existence: Section 4.3.1
testing the context stack: Section 4.3.2
testing token types: Section 4.3.5
.text: Section 6.1, Section 6.5.1, Section 6.6, Section 6.7, Section 6.8, Section 6.9
_TEXT: Section 7.4.2
TIMES: Section 3.2, Section 3.2.5, Section 3.7, Section 10.1.3, Section 10.1.4
TLINK: Section 7.2.2
trailing colon: Section 3.1
two-pass assembler: Section 3.7
TWORD: Section 2.2.7, Section 3.1
type, of symbols: Section 6.5.3
UMOV: Section A.161
unary operators: Section 3.5.7
underscore, in C symbols: Section 7.4.1
uninitialised: Section 3.2, Section 3.2.2
uninitialised storage: Section 2.2.7
Unix: Section 1.3.2
Unix source archive: Section 1.3.2
unrolled loops: Section 3.2.5
unsigned division: Section 3.5.6
unsigned modulo: Section 3.5.6
UPPERCASE: Section 2.2.1, Section 6.2.3
USE16: Section 6.2.1
USE32: Section 6.2.1
user-defined errors: Section 4.3.6
user-level assembler directives: Section 4.7
user-level directives: Chapter 5
VAL: Section 7.1.1
valid characters: Section 3.1
variable types: Section 2.2.3
VERR: Section A.162
version number of NASM: Section 4.7.1
VERW: Section A.162
Visual C++: Section 6.3
-w option: Section 2.1.10
WAIT: Section A.163
warnings: Section 2.1.10
WBINVD: Section A.164
Win32: Section 1.3.1, Section 2.1.1, Section 6.2, Section 6.3, Chapter 8
Windows: Section 7.1
Windows 95: Section 1.3.1
Windows NT: Section 1.3.1
write: Section 6.5.1
writing operating systems: Section 9.1
WRMSR: Section A.165
WRT: Section 3.6, Section 6.2, Section 6.5.2, Section 6.7
WRT ..got: Section 8.2.3
WRT ..gotoff: Section 8.2.2
WRT ..gotpc: Section 8.2.1
WRT ..plt: Section 8.2.5
WRT ..sym: Section 8.2.4
WWW page: Section 1.2
www.delorie.com: Section 7.1.1
www.pcorner.com: Section 7.1.1
www.perl.org: Section 1.3.1
XADD: Section A.166
XBTS: Section A.167
XCHG: Section A.168
x2ftp.oulu.fi: Section 7.1.1
XLATB: Section A.169
XOR: Section A.170

Contents