Assembly Programming: Advantages of Assembly Language
Assembly Programming: Advantages of Assembly Language
CHAPTER 5
Assembly Programming
1. ASSEMBLY LANGUAGE
Each personal computer has a microprocessor that manages the computer's arithmetical, logical,
and control activities. Each family of processors has its own set of instructions for handling various
operations such as getting input from keyboard, displaying information on screen and performing
various other jobs. These set of instructions are called 'machine language instructions'.
A processor understands only machine language instructions, which are strings of 1's and 0's.
However, machine language is too obscure and complex for using in software development. So, the
low-level assembly language is designed for a specific family of processors that represents various
instructions in symbolic code and a more understandable form.
8086 CPU has 8 general purpose registers, each register has its own name:
• AX - the accumulator register (divided into AH / AL).
• BX - the base address register (divided into BH / BL).
• CX - the count register (divided into CH / CL).
3. SEGMENT REGISTERS
5. MEMORY ACCESS
To access memory we can use these four registers: BX, SI, DI, BP.
Combining these registers inside [ ] symbols, we can get different memory locations. These
combinations are supported (addressing modes):
We can form all valid combinations by taking only one item from each column or skipping the
column by not taking anything from it. As we see BX and BP never go together. SI and DI also
don't go together. Here is an example of a valid addressing mode: [BX+5].
The value in segment register (CS, DS, SS, ES) is called a "segment", and the value in purpose
register (BX, SI, DI, BP) is called an "offset". When DS contains value 1234h and SI contains the
value 7890h it can be also recorded as 1234:7890. The physical address will be 1234h * 10h +
7890h = 19BD0h.
Prepared by: Yohannes Bekuma 1 Wollega university, Nekemte
COMPUTER ARCHITECTURE AND ORGANIZATION (ECEG 3143)
In order to say the compiler about data type, these prefixes should be used:
BYTE PTR - for byte.
WORD PTR - for word (two bytes).
For example:
BYTE PTR [BX] ; byte access.
or
WORD PTR [BX] ; word access.
Emu8086 supports shorter prefixes as well:
b. - for BYTE PTR
w. - for WORD PTR
Variables
Variable is a memory location. For a programmer it is much easier to have some value be kept in a
variable named "var1" then at the address 5A73:235B, especially when you have 10 or more
variables.
Our compiler supports two types of variables: BYTE and WORD.
Syntax for a variable declaration:
name DB value
name DW value
name - can be any letter or digit combination, though it should start with a letter. It's possible to
declare unnamed variables by not specifying the name (this variable will have an address but no
name).
value - can be any numeric value in any supported numbering system (hexadecimal, binary, or
decimal), or "?" symbol for variables that are not initialized.
MOV – MOV Destination, Source: The MOV instruction copies a word or byte of data from a
specified source to a specified destination. The destination can be a register or a memory location.
The source can be a register, a memory location or an immediate number. The source and
destination cannot both be memory locations. They must both be of the same type (bytes or words).
MOV instruction does not affect any flag.
• MOV CX, 037AH Put immediate number 037AH to CX
• MOV BL, [437AH] Copy byte in DS at offset 437AH to BL
• MOV AX, BX Copy content of register BX to AX
• MOV DL, [BX] Copy byte from memory at [BX] to DL
• MOV DS, BX Copy word from BX to DS register
Prepared by: Yohannes Bekuma 1 Wollega university, Nekemte
COMPUTER ARCHITECTURE AND ORGANIZATION (ECEG 3143)
XCHG – XCHG Destination, Source: The XCHG instruction exchanges the content of a register
with the content of another register or with the content of memory location(s). It cannot directly
exchange the content of two memory locations. The source and destination must both be of the
same type (bytes or words). The segment registers cannot be used in this instruction. This
instruction does not affect any flag.
• XCHG AX, DX Exchange word in AX with word in DX
• XCHG BL, CH Exchange byte in BL with byte in CH
MUL – MUL Source: This instruction multiplies an unsigned byte in some source with an
unsigned byte in AL register or an unsigned word in some source with an unsigned word in AX
register. The source can be a register or a memory location. When a byte is multiplied by the
content of AL, the result (product) is put in AX. When a word is multiplied by the content of AX,
the result is put in DX and AX registers. If the most significant byte of a 16-bit result or the most
significant word of a 32-bit result is 0, CF and OF will both be 0’s. AF, PF, SF and ZF are
undefined after a MUL instruction.
when operand is a byte: AX = AL * operand.
when operand is a word: (DX AX) = AX * operand.
➢ MUL BH Multiply AL with BH; result in AX
DIV – DIV Source: This instruction is used to divide an unsigned word by a byte or to divide an
unsigned double word (32 bits) by a word. When a word is divided by a byte, the word must be in
the AX register. The divisor can be in a register or a memory location. After the division, AL will
contain the 8-bit quotient, and AH will contain the 8-bit remainder. When a double word is divided
by a word, the most significant word of the double word must be in DX, and the least significant
word of the double word must be in AX. After the division, AX will contain the 16-bit quotient and
DX will contain the 16-bit remainder. If an attempt is made to divide by 0 or if the quotient is too
large to fit in the destination (greater than FFH / FFFFH), the 8086 will generate a type 0 interrupt.
All flags are undefined after a DIV instruction.
If we want to divide a byte by a byte, we must first put the dividend byte in AL and fill AH with all
0’s. Likewise, if we want to divide a word by another word, then put the dividend word in AX and
fill DX with all 0’s.
when operand is a byte:
AL = AX / operand
AH = remainder (modulus). .
when operand is a word:
AX = (DX AX) / operand
DX = remainder (modulus).
INC – INC Destination: The INC instruction adds 1 to a specified register or to a memory
location. AF, OF, PF, SF, and ZF are updated, but CF is not affected. This means that if an 8-bit
destination containing FFH or a 16-bit destination containing FFFFH is incremented, the result will
be all 0’s with no carry.
➢ INC BL Add 1 to contains of BL register
➢ INC CX Add 1 to contains of CX register
➢ INC BYTE PTR [BX] Increment byte in data segment at offset contained in BX.
➢ INC WORD PTR [BX] Increment the word at offset of [BX] and [BX + 1]
in the data segment.
DEC – DEC Destination: This instruction subtracts 1 from the destination word or byte. The
destination can be a register or a memory location. AF, OF, SF, PF, and ZF are updated, but CF is
not affected. This means that if an 8-bit destination containing 00H or a 16-bit destination
containing 0000H is decremented, the result will be FFH or FFFFH with no carry (borrow).
➢ DEC CL Subtract 1 from content of CL register
➢ DEC BP Subtract 1 from content of BP register
➢ DEC BYTE PTR [BX] Subtract 1 from byte at offset [BX] in DS.
➢ DEC WORD PTR [BP] Subtract 1 from a word at offset [BP] in SS.
Prepared by: Yohannes Bekuma 1 Wollega university, Nekemte
COMPUTER ARCHITECTURE AND ORGANIZATION (ECEG 3143)
➢ DEC COUNT Subtract 1 from byte or word named COUNT in DS.
AND – AND Destination, Source: This instruction ANDs each bit in a source byte or word with
the same numbered bit in a destination byte or word. The result is put in the specified destination.
The content of the specified source is not changed.
The source can be an immediate number, the content of a register, or the content of a memory
location. The destination can be a register or a memory location. The source and the destination
cannot both be memory locations. CF and OF are both 0 after AND. PF, SF, and ZF are updated by
the AND instruction. AF is undefined. PF has meaning only for an 8-bit operand.
➢ AND CX, [SI] AND word in DS at offset [SI] with word in CX register;
Result in CX register
➢ AND BH, CL AND byte in CL with byte in BH; Result in BH
➢ AND BX, 00FFH 00FFH Masks upper byte, leaves lower byte unchanged.
OR – OR Destination, Source: This instruction ORs each bit in a source byte or word with the
same numbered bit in a destination byte or word. The result is put in the specified destination. The
content of the specified source is not changed.
The source can be an immediate number, the content of a register, or the content of a memory
location. The destination can be a register or a memory location. The source and destination cannot
both be memory locations. CF and OF are both 0 after OR. PF, SF, and ZF are updated by the OR
instruction. AF is undefined. PF has meaning only for an 8-bit operand.
➢ OR AH, CL CL ORed with AH, result in AH, CL not changed
➢ OR BP, SI SI ORed with BP, result in BP, SI not changed
➢ OR SI, BP BP ORed with SI, result in SI, BP not changed
➢ OR BL, 80H BL ORed with immediate number 80H; sets MSB of BL to 1
➢ OR CX, TABLE [SI] CX ORed with word from effective address TABLE [SI];
Content of memory is not changed.
XOR – XOR Destination, Source: This instruction Exclusive-ORs each bit in a source byte or
word with the same numbered bit in a destination byte or word. The result is put in the specified
destination. The content of the specified source is not changed.
The source can be an immediate number, the content of a register, or the content of a memory
location. The destination can be a register or a memory location. The source and destination cannot
both be memory locations. CF and OF are both 0 after XOR. PF, SF, and ZF are updated. PF has
meaning only for an 8-bit operand. AF is undefined.
➢ XOR CL, BH Byte in BH exclusive-ORed with byte in CL.
Result in CL. BH not changed.
➢ XOR BP, DI Word in DI exclusive-ORed with word in BP.
Result in BP. DI not changed.
NEG – NEG Destination: This instruction replaces the number in a destination with its 2’s
complement. The destination can be a register or a memory location. It gives the same result as the
invert each bit and add one algorithm.
➢ NEG AL Replace number in AL with its 2’s complement
➢ NEG BX Replace number in BX with its 2’s complement
➢ NEG BYTE PTR [BX] Replace byte at offset BX in DX with its 2’s complement
➢ NEG WORD PTR [BP] Replace word at offset BP in SS with its 2’s complement
CMP – CMP Destination, Source: This instruction compares a byte / word in the specified source
with a byte / word in the specified destination. The source can be an immediate number, a register,
or a memory location. The destination can be a register or a memory location. However, the source
and the destination both cannot be memory locations. The comparison is actually done by
subtracting the source byte or word from the destination byte or word. The source and the
destination are not changed, but the flags are set to indicate the results of the comparison. SF, ZF,
and CF are updated by the CMP instruction. For the instruction CMP CX, BX, the values of CF,
ZF, and SF will be as follows:
CF ZF SF
CX = BX 0 1 0 Result of subtraction is 0
CX > BX 0 0 0 No borrow required, so CF = 0
CX < BX 1 0 1 Subtraction requires borrow, so CF = 1
➢ CMP AL, 01H Compare immediate number 01H with byte in AL
➢ CMP BH, CL Compare byte in CL with byte in BH
➢ CMP CX, TEMP Compare word in DS at displacement TEMP with word at CX
TEST – TEST Destination, Source: This instruction ANDs the byte / word in the specified source
with the byte / word in the specified destination. Flags are updated, but neither operand is changed.
The test instruction is often used to set flags before a Conditional jump instruction.
The source can be an immediate number, the content of a register, or the content of a memory
location. The destination can be a register or a memory location. The source and the destination
cannot both be memory locations. CF and OF are both 0’s after TEST. PF, SF and ZF will be
updated to show the results of the destination. AF is be undefined.
➢ TEST AL, BH AND BH with AL. No result stored; Update PF, SF, ZF.
➢ TEST CX, 0001H AND CX with immediate number 0001H;
No result stored; Update PF, SF, ZF
➢ TEST BP, [BX][DI] AND word are offset [BX][DI] in DS with word in BP.
No result stored. Update PF, SF, and ZF
➢ JMP CONTINUE
This instruction fetches the next instruction from address at label CONTINUE. If the label is in the
same segment, an offset coded as part of the instruction will be added to the instruction pointer to
produce the new fetch address. If the label is another segment, then IP and CS will be replaced with
value coded in part of the instruction. This type of jump is referred to as direct because the
displacement of the destination or the destination itself is specified directly in the instruction.
➢ JMP BX
This instruction replaces the content of IP with the content of BX. BX must first be loaded with the
offset of the destination instruction in CS. This is a near jump. It is also referred to as an indirect
jump because the new value of IP comes from a register rather than from the instruction itself, as in
a direct jump.
JAE / JNB / JNC (JUMP IF ABOVE OR EQUAL / JUMP IF NOT BELOW / JUMP IF NO
CARRY):
If, after a compare or some other instructions which affect flags, the carry flag is 0, this instruction
will cause execution to jump to a label given in the instruction. If CF is 1, the instruction will have
no effect on program execution.
➢ CMP AX, 4371H Compare (AX – 4371H)
JAE NEXT Jump to label NEXT if AX above 4371H
JO (JUMP IF OVERFLOW)
The overflow flag will be set if the magnitude of the result produced by some signed arithmetic
operation is too large to fit in the destination register or memory location. The JO instruction will
cause a jump to the destination given in the instruction, if the overflow flag is set.
1. A near call is a call to a procedure, which is in the same code segment as the CALL instruction.
When the 8086 executes a near CALL instruction, it decrements the stack pointer by 2 and copies
the offset of the next instruction after the CALL into the stack. This offset saved in the stack is
referred to as the return address, because this is the address that execution will return to after the
procedure is executed. A near CALL instruction will also load the instruction pointer with the offset
of the first instruction in the procedure. A RET instruction at the end of the procedure will return
execution to the offset saved on the stack which is copied back to IP.
2. A far call is a call to a procedure, which is in a different segment from the one that contains the
CALL instruction. When the 8086 executes a far call, it decrements the stack pointer by 2 and
copies the content of the CS register to the stack. It then decrements the stack pointer by 2 again
and copies the offset of the instruction after the CALL instruction to the stack. Finally, it loads CS
with the segment base of the segment that contains the procedure, and loads IP with the offset of
the first instruction of the procedure in that segment. A RET instruction at the end of the procedure
will return execution to the next instruction after the CALL by restoring the saved values of CS and
IP from the stack.
➢ CALL MULT
This is a direct within segment (near or intra segment) call. MULT is the name of the procedure.
The assembler determines the displacement of MULT from the instruction after the CALL and
codes this displacement in as part of the instruction.
➢ CALL BX
This is an indirect within-segment (near or intra-segment) call. BX contains the offset of the first
instruction of the procedure. It replaces content of IP with content of register BX.
➢ CALL DIVIDE
This is a direct call to another segment (far or inter-segment call). DIVIDE is the name of the
procedure. The procedure must be declared far with DIVIDE PROC FAR at its start. The assembler
will determine the code segment base for the segment that contains the procedure and the offset of
the start of the procedure. It will put these values in as part of the instruction code.
7. 8086 PROGRAMMING
Sample program:
.code ; indicate start of code segment
.startup ; indicate start of program
mov AX, 0
mov BX, 0000H
mov CX, 0
mov SI, AX
mov DI, AX
mov BP, AX
END ; end of file
The flow of the program is usually top-down and instructions are executed one by one!!!
• In general, an assembly program must include the code segment!!
• Other segments, such as stack segment, data segment are not compulsory
• There are key words to indicate the beginning of a segment as well as the end of a segment. Just
like using main(){} in C++ Programming
• Example
DSEG segment ‘data’ ; define the start of a data segment
(2) DW - The DW directive is used to declare a WORD type variable - A WORD occupies 16 bits
or (2 BYTE).
Declaration examples:
Word DW 1234h
Word2 DW 65535; 0FFFFh, (the max. possible for a WORD)
(3) DD - The DD directive is used to declare a DWORD - A DWORD double word is made up of
32 bits =2 Word's or 4 BYTE.
Declaration examples:
Dword1 DW 12345678h
Dword2 DW 4294967295 ;0FFFFFFFFh.
(4) SEGMENT:
It is used to indicate the start of a logical segment. It is the name given to the the segment.
Example: the code segment is used to indicate to the assembler the start of logical segment.
(6) NAME:
It is used to give a specific name to each assembly module when program consists of several
modules.
Example: PC-BOARD used to name an assembly module which contains the instructions for
controlling a printed circuit board.
(7) OFFSET:
It is an operator which tells the assembler to determine the offset or displacement of a named data
item from the start of the segment which contains it. It is used to load the offset of a variable into a