The Intel 80x86 Processor

The Intel Family:

model      reg   bus   mem
8088      16      8      1Mb
8086      16      16      1Mb
80286      16      16      16Mb
80386      32      32      4GB
80486      32      32      4GB
P5         32      64      4GB
Starting with the 80286, Intel processors offer two modes of operation: real mode: one program at a time
protected mode: multi tasking enabled
Later models also offer advanced architectural features that greatly increase speed.

Viewing the Machine

Run a program under the VC++ debugger (press the F5 key). Close all of the windows, then from [View]/[Debug Windows] menu select [Memory], [Registers], and [Disassembly]. Arrange the windows in your main window as shown below:

The [Disassembly] window shows the assembly language translation of our program. The [Memory] window shows the entire contents of memory. The [Registers] window shows the values of all registers.

Memory Model

The [Memory] window shows the contents of all 2^32 bytes of memory. Of course most of these bytes ate 00. By resizing the window we can control the word size being displayed. The right column interprets the bytes as characters:

Intel processors are little endian machines that require words to be aligned.

All addresses are assumed to be offsets from the beginning of a segment:

ADDRESS = SEGMENT * 16 + OFFSET Register Set

The I8x86 processors have four general purpose 32-bit registers:

eax, ebx, ecx, edx In addition, there are two 32-bit index registers, which can be used for copying strings: esi = source index
edi = destination index
There are four control registers: eip = instruction pointer
esp = stack pointer
ebp = base pointer
efl = flags register
There are six 16-bit segment registers: cs = code segment
ds = data segment
ss = stack segment
es = extra segment
fs, gs = extra segments



Flags

OF = V (overflow flag)
CF = C (carry flag)
ZF = Z (zero flag)
SF = N (sign flag)
Instruction Set

Move

mov ARG1, ARG2 /* ARG1 = ARG2 */ Arithmetic add ARG1, ARG2 /* ARG1 += ARG2 */
sub ARG1, ARG2 /* ARG1 -= ARG2 */
neg ARG1 /* ARG1 = -ARG1 */
cmp ARG1, ARG2 /* alu = ARG1 - ARG2 */
Bitwise Operations and ARG1, ARG2 /* ARG1 &= ARG2 */
or ARG1, ARG2 /* ARG1 |= ARG2 */
xor ARG1, ARG2 /* ARG1 ^= ARG2 */
not ARG1 /* ARG1 = ~ARG1 */
Shifts shr ARG1, ARG2 /* ARG1 = ARG1 >> ARG2 */
sal ARG1, ARG2 /* ARG1 = ARG1 << ARG2 */
shl ARG1, ARG2 /* ARG1 = ARG1 <<< ARG2 */
ror ARG1, ARG2 /* ARG1 >>>> ARG2 */
rol ARG1, ARG2 /* ARG1 <<<< ARG2 */
Jumps

Unconditional

jmp LABEL /* goto LABEL */
call PROC /* PROC() */
ret /* return */
Conditional jXX LABEL /* if (XX) goto LABEL */ Where XX = 1. unsigned: a, ae, b, be, c, nc
2. signed: g, ge, l, le, o, no
3. flags: e, ne, s, ns, cxz, p, np
For example: cmp eax, ebx /* alu = eax - abx */
jl LABEL /* if (SF != OF && ZF = 0) goto LABEL */
In other words: if (eax < ebx) goto LABEL Arguments mov eax, 42 /* eax = 42 */
mov eax, x /* eax = x */
mov ebx, OFFSET x /* eax = &x */
mov eax, [ebx] /* eax = *ebx */
mov eax, x[42] /* eax = x[42] */
Tuning a Program

We can insert a block of assembly code into a VC program using an _asm block:

void main()
{
TOP:
   PROMPT("Enter a number: ");
   GETWORD(mem[0]);
   _asm
   {
      mov eax, mem[0] ; load
      add eax, eax    ; add eax to itself
      mov reg0, eax   ; store
   }
   PROMPT("double your number = ");
   PUTWORD(reg0);
   NEWLINE();
   goto TOP;
   return;
}
 
The practice of inserting assembly code into a high-level program is called tuning.
Often code that is frequently executed will be written in assembly. Be careful, this means your program can't be ported to a different platform.

Here's a program that computes the number of bricks to build a staircase of
height n (i.e., the nth triangle number). It does so by simply summing all
of the non-negative integers below n:

 
void main()
{
TOP:
 PROMPT("Enter height of staircase: ");
 GETWORD(mem[0]);
 _asm
 {
  mov eax, mem[0]
  mov ebx, 0
AGAIN:
  cmp eax, 0   ; alu = eax - 0
  jbe DONE     ; if (eax <= 0) goto DONE
  add ebx, eax
  sub eax, 1
  jmp AGAIN
DONE:
  mov reg0, ebx
 }
 PROMPT("# steps required = ");
 PUTWORD(reg0);
 NEWLINE();

 goto TOP;

 return;
}