Logo  

CS351 - Computer Organization

Machine Language / Instructions

Comparing data

To compare data (and set the appropriate flags,) without modifying a register we have the following instructions:

TEST

TEST arg1, arg2

  • arg1: may be a Register or Memory location (R/M)
  • arg2: may be a Register or Immediate value (R/I)

Test performs a bit-wise logical AND between arg1 and arg2 (discarding result) setting the following flags:

flags: Result:
SF MostSignificantBit(result)
ZF (result == 0)
PF 1 iff result has even number of bits
CF 0
OF 0
AF undefined

CMP

CMP arg1, arg2

  • arg1: may be a Register or Memory location (R/M)
  • arg2: may be a Register, Immediate value or Memory (requires arg1 be a Register) (R/I/M)

Comparison (signed subtraction of arg2 from arg1), result is discarded.

Flags affected: SF,ZF,PF,CF,OF,AF

OR

OR reg, reg

If both arguments are the same register, ORing the register with itself will not modify the value of the register, but will set the flags indicating that it is zero or not and the state of the sign bit (i.e. the upper most bit,) which can be used by the jump instructions. This faster than using CMP to test a register for zero or positive/negative.

Jumps

Normally the instruction pointer points the next instruction and is simply incremented to the next instruction as instructions are loaded from memory. A jump is when the code branches to a new location in memory. This is accomplished by a jump instruction that loads a new address into the instruction pointer where the CPU will pull the next instruction from.

Jump statements come in two forms, un-conditional jumps, i.e. the jump is always taken and conditional, i.e. the jump is taken only if some condition (i.e. state of the flags) is met.

JMP

JMP location

Always jumps to location which may be an Immediate address, or an address stored in a Register or Memory.

Jcc - Jump if condition is met

Jcc location

Where cc above is replaced by a condition, such as E for equal, LE for less than or equal, etc. Conditional jumps always only take an immediate address and cannot use a register or memory as the location to jump to.

Below are a small selection of the more important conditional jumps. There are many more (even more than listed in the handout)

Jump if: Flags:
JE loc Equal ZF == 1
JNE loc Not equal ZF == 0
JG loc Greater than SF == OF and ZF == 0
JGE loc Greater than or equal SF == OF or ZF == 1
JL loc Lesser than SF != OF
JLE loc Lesser than or equal SF != OF or ZF == 1
JZ loc Jump if zero ZF == 1
JNZ loc Jump if not zero ZF == 0

Higher level language to Assembly conversion

What follows are common conversions from a higher level language to assembly.

Note that the labels used in the assembly should be customized to the code being written. Consider appending numbers to the labels to make them unique and if you need to nest them, i.e. .while0:, etc.

The "instruction" jcc below represents one of the conditional jump instructions and should not be taken literally.

The if statement

          C code:                             Assembly Code:
─────────────────────────────────────────────────────────────────────────
                                 ┊
      ┌────────────┐             ┊               ┌────────────┐
 if ( │ expression │ ) { ──────────────────────▷ │ expression │
      └────────────┘             ┊               └────────────┘
   ┌────────────┐                ┊               jcc .else            ───┐
   │ statements ├───────────────────┐                                    │
   └────────────┘                ┊  │          ┌ ┌────────────┐ ┐        │
                                 ┊  └─────────▷│ │ statements │ │        │
 } else {                        ┊             │ └────────────┘ │        │
                                 ┊             └ jmp .done      ┘     ─────┐
   ┌─────────────────┐           ┊                                       │ │
   │ else-statements ├───────────────┐   .else:                       ◁──┘ │
   └─────────────────┘           ┊   │           ┌─────────────────┐       │
                                 ┊   └─────────▷ │ else-statements │       │
 }                               ┊               └─────────────────┘       │
                                 ┊                                         │
                                 ┊       .done:                       ◁────┘
 ┌─────────────────┐             ┊               ┌─────────────────┐
 │ More statements ├───────────────────────────▷ │ More statements │
 └─────────────────┘             ┊               └─────────────────┘


In the case of an if statement with no matching else part, then:

  1. The .else: label and else-statements, and the jmp .done after statements are all omitted.
  2. The conditional jump below the expression is changed to jump to the .done label

The while style loop

          C code:                             Assembly Code:
─────────────────────────────────────────────────────────────────────────
 ┌─────────────────┐             ┊               ┌─────────────────┐
 │ init expression ├───────────────────────────▷ │ init expression │
 └─────────────────┘             ┊               └─────────────────┘
                                 ┊       .while:                      ◁──┐
        ┌─────────────────┐      ┊               ┌─────────────────┐     │
 while( │ test expression │ ) {  ──────────────▷ │ test conditions │     │
        └─────────────────┘      ┊               └─────────────────┘     │
                                 ┊               jcc .done            ───│─┐
    ┌────────────┐               ┊                                       │ │
    │ statements ├────────────────┐              ┌────────────┐          │ │
    └────────────┘               ┊└────────────▷ │ statements │          │ │
                                 ┊               └────────────┘          │ │
 }                               ┊               jmp .while           ───┘ │
                                 ┊                                         │
                                 ┊       .done:                       ◁────┘
 ┌─────────────────┐             ┊               ┌─────────────────┐
 │ More statements ├───────────────────────────▷ │ More statements │
 └─────────────────┘             ┊               └─────────────────┘


  • Any break instruction in the C code corresponds to a jmp to .done.
  • Any continue instruction in the C code corresponds to a jmp to .while

NOTE: The conditional branch to .done has the reverse sense to the while statements test expression, i.e. leave the loop if any of the test conditions are false, rather than continuing the loop so long as the test expression is true as in the C case.

The for style loop

          C code:                             Assembly Code:
─────────────────────────────────────────────────────────────────────────
                                 ┊               ┌─────────────────┐
        ┌─────────────────┐      ┊   ┌─────────▷ │ init expression │
  for ( │ init expression │ ; ───────┘           └─────────────────┘
        └─────────────────┘      ┊       .for:
        ┌─────────────────┐      ┊               ┌─────────────────┐
        │ test expression │ ; ─────────────────▷ │ test conditions │
        └─────────────────┘      ┊               └─────────────────┘
        ┌─────────────────┐      ┊               jcc .done
        │ inc. expression │ ) { ──────┐
        └─────────────────┘      ┊    │          ┌────────────┐
                                 ┊ ┌──│────────▷ │ statements │
     ┌────────────┐              ┊ │  │          └────────────┘
     │ statements ├────────────────┘  │  .inc:
     └────────────┘              ┊    │          ┌─────────────────┐
                                 ┊    └────────▷ │ inc. expression │
  }                              ┊               └─────────────────┘
                                 ┊               jmp .for
  ┌─────────────────┐            ┊
  │ More statements ├──────────────┐     .done:
  └─────────────────┘            ┊ │             ┌─────────────────┐
                                 ┊ └───────────▷ │ More statements │
                                 ┊               └─────────────────┘


  • Any break instruction in the C code corresponds to a jmp to .done.
  • Unlike in the while case, any continue instruction in the C code corresponds to a jmp to .inc

The do-while style loop

The C do-while loop loops at least once. It is also the most natural loop style to do in assembly if one knows they are going to loop at least once as it requires only a single conditional jump in order to repeat the loop.

          C code:                             Assembly Code:
─────────────────────────────────────────────────────────────────────────
                                 ┊
 do {                            ┊       .do:                         ◁──┐
                                 ┊                                       │
    ┌────────────┐               ┊               ┌────────────┐          │                  
    │ statements ├─────────────────────────────▷ │ statements │          │
    └────────────┘               ┊               └────────────┘          │
                                 ┊                                       │
                                 ┊       .continue:                      │
        ┌─────────────────┐      ┊               ┌─────────────────┐     │
 while( │ test expression │ ) ;  ──────────────▷ │ test conditions │     │
        └─────────────────┘      ┊               └─────────────────┘     │
                                 ┊               jcc .do              ───┘
                                 ┊
                                 ┊       .break:
 ┌─────────────────┐             ┊               ┌─────────────────┐
 │ More statements ├───────────────────────────▷ │ More statements │
 └─────────────────┘             ┊               └─────────────────┘


NOTE: The break and continue labels are unnecessary if you have no break or continue statements that require them.

  • Any break instruction in the C code corresponds to a jmp to .break.
  • Any continue instruction in the C code corresponds to a jmp to .continue