Programming in Assembly Language
SP (stack pointer) points to the top of the
processor's stack
CS 272
Sam Houston State Univ. BP (base pointer) usually accesses data on the
Dr. Tim McGuire stack
SI (source index) used to point to memory locations
Memory Segmentation in the data segment
DI (destination index) performs same functions as
Memory segments are a direct consequence of SI.
using a 20 bit address in a 16 bit processor DI and SI are often used for string operations
Memory is partitioned into 64K (216) segments
Each segment is identified by a 16-bit segment Segment Registers: CS, DS, SS, ES
number ranging from 0000h-FFFFh
Within a segment, a memory location is specified by
a 16-bit offset (the number of bytes from the
CS (code segment) addresses the start of the
program's machine code in memory
beginning of the segment)
The Segment:Offset address is a logical address
DS (data segment) addresses the start of the
program's data in memory
SS (stack segment) addresses the start of the
Segment:Offset Addresses program's stack space in memory
ES (extra segment) addresses and additional data
A4FB:4872h means offset 4872h within segment segment, if necessary
A4FBh
To get the physical address, the segment number is Instruction Pointer: IP
multiplied by 16 (shifted 4 bits to the left) and the
offset is added
A4FB0h + 4872h = A9822h (20 bit physical
8086 uses registers CS and IP to access
instructions
address)
There is a lot of overlap between segments; a new
CS register contains the segment number of the
next instruction and the IP contains the offset
segment begins every 16 bytes (addresses ending
in 0h) The IP is updated each time an instruction is
We call these 16 bytes a paragraph
executed so it will point to the next instruction
Because segments may overlap, the segment:offset
The IP is not directly accessible to the user
address is not unique
The FLAGS register
8086 Registers
Indicates the status of the microprocessor
Information inside the microprocessor is stored in Two kinds of flag bits: status flags and control flags
registers (fourteen 16-bit registers) Status flags reflect the result of an instruction, e.g.,
data registers hold data for an operation when the result of an arithmetic operation is 0, ZF
address registers hold the address of an instruction
(zero flag) is set to 1 (true)
or data Control flags enable or disable certain operations of
The address registers are divided into segment,
the processor, e.g., if the IF (interrupt flag) is cleared
(set to 0), inputs from the keyboard are ignored by
pointer, and index registers
the processor
a status register (called FLAGS) keeps the current
status of the processor
Instructions Groups and Concepts
Data Registers: AX, BX, CX, and DX
Data Transfer Instructions
Available to the programmer for general data
Arithmetic Instructions
manipulation Logic Instructions
Some operations require a particular register Flow-control Instructions
High and low bytes of data registers can be Processor Control Instructions
accessed separately, i.e., AX is divided into AH and String Instructions
AL
AX (accumulator) is preferred for arithmetic, logic,
Data Transfer Instructions
and data transfer operations
BX (base register) serves as an address register
CX (count register) frequently serves as a loop General instructions
counter
DX (data register) is used in multiplication and o mov, pop, push, xchg, xlat/xlatb
division
Input/Output instructions
Pointer and Index Registers: SP, BP, SI, DI
o in, out
Address instructions
o lds, lea, les o SP is increased by 2
Flag instructions
Stack example
o lahf, popf, pushf, sahf push ax ;Save ax and bx
push bx ; on the stack
General Instructions mov ax, -1 ;Assign test values
mov bx, -2
mov cx, 0
mov destination, source mov dx, 0
push ax ;Push ax onto stack
pop destination push bx ;Push bx onto stack
push source pop cx ;Pop cx from stack
xchg destination, source
pop dx
pop bx
;Pop dx from stack
;Restore saved ax and bx
xlat(b)table pop ax ; values from stack
Note that the destination comes first, just as in an
Arithmetic Instructions
assignment statement in C
Examples Addition instructions
mov ax, [word1] o aaa, adc, add, daa, inc
Subtraction instructions
o "Move word1 to ax"
o Contents of register ax are replaced by o aas, cmp, das, dec, neg, sbb, sub
the contents of the memory location Multiplication instructions
word1
o The brackets specify that the contents of
word1 are stored -- word1==address, o aam, imul, mul
[word1]==contents
Division instructions
xchg ah, bl
o aad, cbw, cwd, div, idiv
o Swaps the contents of ahand bl
Illegal: mov [word1], [word2] Addition Instructions
o can't have both operands be memory
aaa
locations
The Stack o ASCII adjust for addition
adc destination, source
A data structure in which items are added and
removed only from one end (the "top") o Add with carry
A program must set aside a block of memory to hold add destination, source
the stack by declaring a stack segment
o Add bytes or words
stack 256
daa
o Decimal adjust for addition
SS will contain the segment number of the stack inc destination
segment -- SP will be initialized to 256 (100h)
The stack grows from higher memory addresses to
o Increment
lower ones
ADD and INC
PUSH and POP
New words are added with push
ADD is used to add the contents of
push source
o two registers
o a register and a memory location
o SP is decreased by 2
o a register and a constant
o a copy of the source contents is moved
to SS:SP INC is used to add 1 to the contents of a register or
memory location
Items are removed with pop
pop destination
Examples
o Content of SS:SP is moved to the
destination add ax, [word1]
o "Add word1to ax" o Integer (signed) multiply
o Contents of register ax and memory mul source
location word1 are added, and the sum
is stored in ax
inc ah o Unsigned multiply
Byte and Word Multiplication
o Adds one to the contents of ah
Illegal: add [word1], [word2]
If two bytes are multiplied, the result is a 16-bit word
o can't have both operands be memory If two words are multiplied, the result is a 32-bit
locations doubleword
For the byte form, one number is contained in the
source and the other is assumed to be in al -- the
Subtraction instructions
product will be in ax
For the word form, one number is contained in the
aas source and the other is assumed to be in ax -- the
most significant 16 bits of the product will be in dx
and the least significant 16 bits will be in ax
o ASCII adjust for subtraction
cmp destination, source Examples
o Compare If ax contains 0002h and bx contains 01FFh
das
mul bx
o Decimal adjust for subtraction
dx = 0000h ax = 03FEh
dec destination
o Decrement byte or word
If ax contains 0001h and bx contains FFFFh
neg destination
mul bx
o Negate (two's complement) dx = 0000h ax = FFFFh
sbb destination, source imul bx
dx = FFFFh ax = FFFFh
o Subtract with borrow
sub destination, source Division instructions
o Subtract aad
Examples o ASCII adjust for divide
cbw
sub ax, [word1]
o convert byte to word
o "Subtract word1 from ax" cwd
o Contents of memory location word1 is
subtracted from the contents of register
ax, and the sum is stored in ax o convert word to doubleword
dec bx div source
o Subtracts one from the contents of bx o unsigned divide
Illegal: sub [byte1], [byte2] idiv source
o can't have both operands be memory o integer (signed) divide
locations
Byte and Word Division
Multiplication instructions
When division is performed, there are two results,
aam the quotient and the remainder
These instructions divide 8 (or 16) bits into 16 (or 32)
bits
o ASCII adjust for multiply
Quotient and remainder are same size as the divisor
imul source
For the byte form, the 8 bit divisor is contained in the o Test bits
source and the dividend is assumed to be in ax -- xor destination, source
the quotient will be in al and the remainder in ah
For the word form, the 16 bit divisor is contained in
the source and the dividend is assumed to be in
o Logical Exclusive OR
dx:ax -- the quotient will be in ax and the remainder
in dx
The ability to manipulate bits is one of the
advantages of assembly language
Examples
One use of and, or, and xor is to selectively modify
the bits in the destination using a bit pattern (mask)
If dx = 0000h, ax = 00005h, and bx = 0002h The and instruction can be used to clear specific
destination bits
div bx
The or instruction can be used to set specific
destination bits
ax = 0002h dx = 0001h The xor instruction can be used to complement
specific destination bits
If dx = 0000h, ax = 0005h, and bx = FFFEh
Examples
div bx
To clear the sign bit of al while leaving the other bits
ax = 0000h dx = 0005h unchanged, use the and instruction with 01111111b
=7Fh as the mask
idiv bx
ax = FFFEh dx = 0001h and al,7Fh
Divide Overflow
To set the most significant and least significant bits
of al while preserving the other bits, use the or
It is possible that the quotient will be too big to fit in instruction with 10000001b = 81h as the mask
the specified destination (al or ax)
This can happen if the divisor is much smaller than or al,81h
the dividend
When this happens, the program terminates and the
system displays the message "Divide Overflow" To change the sign bit of dx, use the xor instruction
with a mask of 8000h
Sign Extension of the Dividend
xor dx,8000h
Word division The NOT instruction
o The dividend is in dx:ax even if the The not instruction performs the one's complement
actual dividend will fit in ax operation on the destination
o For div, dx should be cleared The format is
o For idiv, dx should be made the sign
extension of ax using cwd
o not destination
Byte division
To complement the bits in ax:
o The dividend is in ax even if the actual
dividend will fit in al o not ax
o For div, ah should be cleared To complement the bits in WORD1
o For idiv, ah should be made the sign
extension of al using cbw
o not [WORD1]
Logic Instructions
The TEST instruction
and destination, source
The test instruction performs an and operation of
the destination with the source but does not change
o Logical AND the destination contents
not destination The purpose of the test instruction is to set the
status flags (discussed later)
o Logical NOT (one's complement)
Status Flags
or destination, source
Bit Name Symbol
o Logical OR
test destination, source
0
2
Carry flag
Parity flag
cf
pf
4 Auxiliary carry flag af
Zeros are shifted into the rightmost bit positions and
6 Zero flag zf
the last bit shifted out goes into CF
7 Sign flag sf
11 Overflow flag of Effect on flags:
The Carry Flag (CF) o SF, PF, ZF reflect the result
o AF is undefined
o CF = last bit shifted out
CF = 1 if there is a carry out from the msb (most
significant bit) on addition, or there is a borrow into
o OF = 1 if result changes sign on last shift
the msb on subtraction
CF = 0 otherwise SHL example
CF is also affected by shift and rotate instructions
dh contains 8Ah and cl contains 03h
The Parity Flag (PF) dh = 10001010, cl = 00000011
after shl dh,cl
PF = 1 if the low byte of a result has an even
number of one bits (even parity) o dh = 01010000, cf = 0
PF = 0 otherwise (odd parity)
The SAL instruction
The Auxiliary Carry Flag (AF)
The shl instruction can be used to multiply an
AF = 1 if there is a carry out from bit 3 on addition, or operand by powers of 2
there is a borrow into the bit 3 on subtraction
To emphasize the arithmetic nature of the operation,
AF = 0 otherwise the opcode sal (shift arithmetic left) is used in
AF is used in binary-coded decimal (BCD) instances where multiplication is intended
operations Both instructions generate the same machine
code
The Zero Flag (ZF)
Right Shift Instructions
ZF = 1 for a zero result
ZF = 0 for a non-zero result The SHR (shift right) instruction shifts the bits in the
destination to the right.
Zeros are shifted into the leftmost bit positions and
The Sign Flag (SF)
the last bit shifted out goes into CF
Effect on flags:
SF = 1 if the msb of a result is 1; it means the result
is negative if you are giving a signed interpretation
o SF, PF, ZF reflect the result
SF = 0 if the msb is 0
o AF is undefined
o CF = last bit shifted out
The Overflow Flag (OF) o OF = 1 if result changes on last shift
OF = 1 if signed overflow occurred SHR example
OF = 0 otherwise
dh contains 8Ah and cl contains 02h
Shift Instructions dh = 10001010, cl = 00000010
after shr dh,cl
Shift and rotate instructions shift the bits in the
destination operand by one or more positions either o dh = 001000010, cf = 1
to the left or right
The instructions have two formats:
The SAR instruction
o opcode destination, 1
o opcode destination, cl
The sar (shift arithmetic right) instruction can be
used to divide an operand by powers of 2
The first shifts by one position, the second shifts by
N positions, where cl contains N (cl is the only sar operates like shr, except the msb retains its
original value
register which can be used)
The effect on the flags is the same as for shr
Left Shift Instructions If unsigned division is desired, shr should be used
instead of sar
The SHL (shift left) instruction shifts the bits in the Rotate Instructions
destination to the left.
Rotate Left Table 4.6 (and Table 16.4) shows all the conditional
jumps
o The instruction rol (rotate left) shifts The destination_label must precede the jump
instruction by no more than 126 bytes, or follow it by
bits to the left
no more than 127 bytes
o The msb is shifted into the rightmost bit
o The cf also gets the the bit shifted out of
There are ways around this restriction (using the
unconditional jmp instruction)
the msb
Rotate Right
The CMP Instruction
o ror (rotate right) rotates bits to the right
o the rightmost bit is shifted into the msb The jump condition is often provided by the cmp
and also into the cf (compare) instruction:
Rotate through Carry cmp destination, source
Rotate through Carry Left cmp is just like sub, except that the destination is
not changed -- only the flags are set
Suppose ax = 7FFFh and bx = 0001h
o The instruction rcl shifts bits to the left
o The msb is shifted into cf
cmp ax, bx
o cf is shifted into the rightmost bit
jg below
Rotate through Carry Right
zf = 0 and sf = of = 0, so control transfers to label below
o rcr rotates bits to the right Types of Conditional Jumps
o The rightmost bit is shifted into cf
o cf is shifted into the msb
See SHIFT.ASM for an example
Signed Jumps:
Flow-Control Instructions o jg/jnle, jge/jnl, jl/jnge, jle/jng
Unsigned Jumps:
%TITLE "IBM Character Display -- XASCII.ASM"
IDEAL
MODEL small o ja/jnbe, jae/jnb, jb/jnae, jbe/jna
STACK 256 Single-Flag Jumps:
CODESEG
Start: mov ax, @data ; Initialize DS to address
mov ds, ax ; of data segment o je/jz, jne/jnz, jc, jnc, jo, jno, js, jns,
mov ah, 02h ; display character function jp/jpe, jnp/jpo
mov cx,256 ; no. of chars to display
mov dl, 0 ; dl has ASCII code of null char
Ploop: int 21h ; display a character Signed versus Unsigned Jumps
inc dl ; increment ASCII code
dec cx ; decrement counter
jnz Ploop ; keep going if cx not zero Each of the signed jumps has an analogous
Exit: mov ah, 04Ch ; DOS function: Exit program unsigned jump (e.g., the signed jump jg and the
mov al, 0 ; Return exit code value unsigned jump ja)
int 21h ; Call DOS. Terminate program Which jump to use depends on the context
END Start ; End of program / entry point
Using the wrong jump can lead to incorrect results
Conditional Jumps When working with standard ASCII character, either
signed or unsigned jumps are OK (msb is always 0)
jnz is an example of a conditional jump
When working with the IBM extended ASCII codes,
use unsigned jumps
Format is
Conditional Jump Example
jxxx destination_label
Suppose ax and bx contained signed numbers.
If the condition for the jump is true, the next Write some code to put the biggest one in cx:
instruction to be executed is the one at
destination_label.
mov cx,ax ; put ax in cx
If the condition is false, the instruction immediately cmp bx,cx ; is bx bigger?
following the jump is done next jle NEXT ; no, go on
For jnz, the condition is that the result of the mov cx,bx ; yes, put bx in cx
previous operation is not zero NEXT:
The JMP Instruction
Range of a Conditional Jump
jmp causes an unconditional jump
jmp destination
jmp can be used to get around the range restriction Multi-way branch structure with following form:
of a conditional jump
e.g, (this example can be made shorter, how?) case expression
value1 : statement1
TOP: TOP: value2 : statement2
; body of loop ; body of loop …
; over 126 bytes dec cx valuen : statementn
endcase
dec cx jnz BOTTOM
jnz TOP jmp EXIT
mov ax, bx BOTTOM:
jmp TOP Example -- If ax contains a negative number, put -1
EXIT: in bx; if 0, put 0 in bx; if positive, put 1 in bx:
mov ax, bx
case ax
Branching Structures < 0: put -1 in bx
= 0: put 0 in bx
> 0: put 1 in bx
IF-THEN endcase
IF-THEN-ELSE
CASE
This example may be coded as:
AND conditions
OR conditions ; case ax
cmp ax, 0 ; test ax
IF-THEN structure jl neg ; ax < 0
je zero ; ax = 0
jg pos ; ax > 0
Example -- to compute |ax|: neg:
mov bx, -1
jmp endcase
if ax < 0 then zero:
ax = -ax xor bx,bx ; put 0 in bx
endif jmp endcase
pos:
mov bx, 0
Can be coded as: endcase:
; if ax < 0
cmp ax, 0 ; ax < 0 ?
Only one cmp is needed, because jump instructions
do not affect the flags
jnl endif ; no, exit
; then
neg ax ; yes, change sign AND conditions
; endif
IF-THEN-ELSE structure Example -- read a character and display it if it is
uppercase:
Example -- Suppose al and bl contain extended
ASCII characters. Display the one that comes first in read a character into al
the character sequence: if char >= 'A' and char <= 'Z' then
display character
endif
if al <= bl then
display the character in al ; read a character
else mov ah, 1 ;prepare to read
display the character in bl int 21h ;char in al
endif ; if char >= 'A' and char< = 'Z'
cmp al,'A' ;char >= 'A'?
jnge endif ;no, exit
This example may be coded as: cmp al,'Z' ;char <= 'Z'?
jnle endif ;no, exit
;then display character
mov ah, 2 ; prepare for display
mov dl,al ;get char
; if al <= bl
mov ah,2 ;prep for display
cmp al, bl ; al <= bl ?
int 21h ;display char
jnbe else ; no, display bl
endif:
; then ; al <= bl
mov dl, al ; move it to dl OR conditions
jmp display
else: ; bl < al
mov dl, bl Example -- read a character and display it if it is 'Y'
display:
or 'y':
int 21h ; display it
; endif
read a character into al
The CASE structure if char = 'y' or char = 'Y' then
display character
endif
; read a character jcxz SKIP
mov ah, 1 ;prepare to read TOP:
int 21h ;char in al ; body of loop
; if char = 'y' or char = 'Y' loop TOP
cmp al,'y' ;char = 'y'? SKIP:
je then ;yes, display it
cmp al,'Y' ;char = 'Y'? The WHILE Loop
je then ;yes, display it
jmp endif ;no, exit while condition do
then: statements
mov ah,2 ;prep for display endwhile
mov dl,al ;move char
int 21h ;display char
endif: The condition is checked at the top of the loop
The loop executes as long as the condition is true
Looping Structures
The loop executes 0 or more times
FOR loop WHILE example
WHILE loop
REPEAT loop
Count the number of characters in an input line
The FOR Loop
count = 0
read char
The loop statements are repeated a known number
while char <> carriage_return do
increment count
of times (counter-controlled loop)
read char
endwhile
for loop_count times do
statements mov dx,0 ;DX counts chars
endfor mov ah,1 ;read char fnctn
int 21h ;read char into al
WHILE_:
The loop instruction implements a FOR loop: cmp al,0Dh ;ASCII CR?
je ENDWHILE ;yes, exit
inc dx ;not CR, inc count
loop destination_label int 21h ;read another char
jmp WHILE_ ;loop back
ENDWHILE:
The counter for the loop is the register cx which is
initialized to loop_count
The loop instruction causes cx to be decremented, The label WHILE_ is used because WHILE is a
and if cx¹ 0, jump to destination_label reserved word
The REPEAT Loop
The destination label must precede the loop
instruction by no more than 126 bytes repeat
A FOR loop can be implemented as follows: statements
until condition
;initialize cx to loop_count
TOP: The condition is checked at the bottom of the loop
;body of the loop
loop TOP The loop executes until the condition is true
The loop executes 1 or more times
FOR loop example
REPEAT example
a count-controlled loop to display a row of 80 stars
read characters until a blank is read
mov cx,80 ; # of stars
mov ah,2 ; disp char fnctn
mov dl,'*' ; char to display repeat
TOP: read character
int 21h ; display a star until character is a blank
loop TOP ; repeat 80 times
mov ah,1 ;read char fnctn
FOR loop "gotcha" REPEAT:
int 21h ;read char into al
;until
The FOR loop implemented with the loop instruction cmp al,' ' ;a blank?
always executes at least once jne REPEAT ;no, keep reading
If cx = 0 at the beginning, the loop will execute
65536 times!
Using a while or a repeat is often a matter of
To prevent this, use a jcxz before the loop personal preference. The repeat may be a little
shorter because only one jump instruction is
required, rather than two
Digression: Displaying a String
We've seen INT 21h, functions 1 and 2, to read and
display a single character
INT 21h, function 9 displays a character string
o Input: dx = offset address of string
o The string must end with a '$' character
-- The '$' is not displayed
The LEA Instruction
INT 21h, function 9, expects the offset address of
the string to be in dx
To get it there, use the lea (load effective address)
instruction
lea destination,source
destination is a register, and source is a memory
location
For example, lea dx, msg puts the offset address of
the variable msg into dx
A digression from our digression -- program segment
prefix (PSP)
DOS prefaces each program it loads with a PSP
The PSP contains information about the program,
including any command line arguments
The segment number of the PSP is loaded in ds, so
ds does not contain the segment number of the
DATASEG
To correct this
mov ax,@data
mov ds,ax
The assembler translates@data into a segment
number
Two instructions are necessary since a number
cannot be moved directly into a segment register
So, back to printing a string...
%TITLE "Print String Program -- PRTSTR.ASM"
IDEAL
MODEL small
STACK 256
DATASEG
msg DB "Hello!$"
CODESEG
Start:
mov ax,@data ;Initialize DS to address
mov ds,ax ; of data segment
lea dx,[msg] ;get message
mov ah,09h ;display string function
int 21h ;display message
Exit:
mov ah,4Ch ;DOS function: Exit program
mov al,0 ;Return exit code value
int 21h ;Call DOS. Terminate program
END Start ;End of program / entry point