386 Assembler Language
We will use the NASM assembler to create some small assembler programs on the PC. Some useful links:
  1. We are using 386 mainly because it's handy. The architecture is not very clean.
  2. We'll be considering the 32-bit architecture. 64-bit systems can do 32-bit just fine. (16-bit ones, too, for that matter.)
  3. We'll use the NASM assembler.
    1. On Linux, just use the package manager, e.g., yum install nasm
    2. For Windows.
      1. You should have the compilers working from the Windows command line. If they don't, you might install MinGW. If you have CodeBlocks installed, you might try this procedure to make the compilers available.
      2. NASM download page.
      3. Nasm is available on Sandbox.
  4. NASM uses the Intel format, rather than the ATT format. (Some of the tutorials may refer to these.)
    The Stack
  5. Furniture.
    1. 32-bit General-purpose registers: EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP.
    2. The Program Counter is called EIP.
    3. The MOV instruction copies between registers, or memory and register.
      Covers load and store, and copying between registers.
    4. Simple math: ADD and SUB. Also INC and DEC.
    5. MUL and DIV.
      1. MUL produces a 64-bit product in EDX:EAX pair.
      2. DIV divides a 64-bit value EDX:EAX.
    6. For two arguments, the first is the destination.
    7. Destinations can be registers or memory addresses.
    8. Sources also can be constants.
    9. Memory locations can be symbols, or indirect from registers.
      [EAX], [ESP+4], [4*EAX+12]
    10. PUSH and .
      1. Manipulate the ESP.
      2. PUSH decrements then stores.
      3. loads then increments.
    11. Assorted jumps.
    12. CALL and RET.
  6. Calling conventions.
    1. Conventional register usage allows functions written by different parties to work together.
    2. Compiled code generally obeys these rules.
    3. The values of EBX, ESI, EDI and EBP must survive across calls.
      1. If you call a function, you can expect it to preserve those registers.
      2. If you write a function, you must either not use those registers, or save before use and restore before return.
    4. Other register may not survive functions you call, and you need not preserve them in your functions.
    5. A function's return value is left in EAX.
    6. Arguments are pushed before calling, and the caller removes them after return.
    7. The EBP is used as frame pointer.
    8. Function form:
      push ebp mov ebp, esp ; Save registers on the stack, several pushes, or pusha sub esp, N ; Allocate N bytes of local variable space ; ; Get some actual work done. ; add esp, N ; Free the space ; Pop saved registers off the stack. mov esp, ebp pop ebp ret