Friday 16 February 2018


CENG 222 – Computer Organization
Lab Work 3

Special Register: FLAGS

The flags register is unlike the other registers on the microprocessor. The other registers hold eight or 16 bit values. The flags register is simply a collection of one bit values which help determine the current state of the processor. Although the flags register is 16 bits wide, some of them are used. Of these flags, four flags you use all the time: zero, carry, sign, and overflow. These flags are the 8086 condition codes. The flags register appears below:
Zero flag bit is set when last instruction produces 0 as a result.
Carry flag bit is set when last instruction produces a number with a carry.
Sign flag bit is set when last instruction produces a negative number.
Overflow flag bit is set when last instruction produces a number which cannot fit in register.

Flag bits are generally used for testing the conditions. For example, if you want to test whether A = B, you need to subtract A from B, then if you have a result 0, zero flag will be set. Therefore, you need to check zero flag to obtain the result of the condition.

Arithmetic operations

Some of the arithmetic operations that are supported by Intel microprocessors are:
ADD, ADC, INC, DEC, SUB, MUL, IMUL, DIV, IDIV

ADD <destination>, <addend>                    ; destination = destination + addend

ADD instruction adds <addend> to <destination>.

ADD ax, bx                ; ax = ax + bx
ADD var, 2                 ; var = var + 2
ADD al, cl                   ; al = al + cl

ADC <destination>, <addend>                    ; destination = destination + addend + C

ADC instruction adds <addend> + Carry to <destination>. It is used to add large sized numbers.
Let AX:BX be 32 bits number. Let CX:DX be another 32 bits number. In order to add these numbers together using 16-bits microprocessor, we need to use ADC.

ADD BX, DX                        ; Add low order digits
ADC AX, CX             ; Add high order digits together with carry

The instructions above simply calculates: (AX:BX) = (AX:BX) + (CX:DX)

INC <destination>                                         ; destination = destination + 1;
DEC <destination>                                       ; destination = destination - 1;

INC instruction increments and DEC instruction decrements the destination.

INC dx
DEX al
INC var


SUB <destination>, <subtrahend>              ; destination = destination – subtrahend

SUB instruction subtracts <subtrahend> from <destination>.

SUB var, 2                  ; var = var - 2;
SUB bl, cl                   ; bl = bl – cl;
SUB bx, ax                 ; bx = bx – ax;

MUL <multiplicand>

MUL instruction multiplies AX or AL register by <multiplicand>. Destination is AX and DX. If <multiplicand> is an 8-bits number, it will be multiplied by AL. The destination is AX. If <multiplicand> is a 16-bits number, it will be multiplied by AX. The destination is (DX:AX). Here are some examples to make it clear:

MUL DL                     ; AX = AL * DL
MUL BX                    ; (DX:AX) = AX * BX
MUL var                     ; AX = AL * var         (Assuming var is a byte)
MUL var                     ; (DX:AX) = AX * var           (Assuming var is a word)

IMUL is the same as MUL, but it is used for signed numbers which are stored in 2’s complement format.

DIV <divisor>

DIV instruction divides AX or (DX:AX) by <divisor>.
If <divisor> is an 8-bits number,
            AL = AX / <divisor>
            AH = AX mod <divisor>
If <divisor> is a 16-bits number,
            AX = (DX:AX) / <divisor>
            DX = (DX:AX) mod <divisor>


Here is piece of code for division.

MOV AX, 1000
MOV DL, 30
DIV DL

The code above divides 1000 by 30. The quotient (33) will be in AL. The remainder (10) will be in AH. If the number is in <divisor> is too small or zero, the quotient will be too large to fit in AL. Therefore you need to select the registers according to their sizes. For example if you want to divide 1000 by 3, you will get 333 as a quotient which cannot be stored in 8-bits register AL! In order to do this, you need to use 16-bits division. Here is how:

MOV AX, 1000          ; The number is 1000.
MOV DX, 0                ; DX = 0, so (DX:AX) is 0000:1000 = 1000.
MOV BX, 3                ; Divisor is 3
DIV BX                      ; AX = (DX:AX) / 3 = 1000 / 3 = 333. AX is capable to store 333.
                                    ; DX = (DX:AX) mod 3 = 1000 mod 3 = 1.

IDIV is the same as DIV, but it is used for signed numbers which are stored in 2’s complement format.

EXPERIMENTS Advanced Arithmetic Operations
I) Write assembly program to do the following substractions.For each value, what is the hexadecimal result? What is the decimal result? Investigate Carry and Sign and Zero Bits.
  • 01h – 01h
  • 00h + 00h
  • 265Ch - 1AFFh.
  • 0000h - 0001h

II)  Write assembly programs to find the sum of the following hexadecimal numbers. For each summation answer following questions. Does the result fit in a 16 bit register? Why? Investigate the Carry and sign bits.
  • 0Fh + 01h
  • FFFFh + 0001h
  • 0FAAh + 1B04h +  F0A0h.

III) Write assembly programs to do the following computations. Chose registers according to the data and state how the resulting number is represented.
  • 03h * 05h
  • A1A1h * 00F0h
  • (A5C4h * 0040h) + 00FFh
  • (A5C4h / 0004h) – 0A0Ah
  • 02h * AAh * F2h



No comments:

Post a Comment