L6 8086 Print Merged
L6 8086 Print Merged
oRemember for out fictitious processor, we had a binary pattern oPrograms written using mnemonics are called assembly level
programs
0020H
oBut ultimately programs should be in machine code since that is
to store the number 0x20 in register 0
the language understood by the processor
oThis binary (hexadecimal) representation of program is what we
refer as machine code oHence somebody should convert assembly level programs to
machine code before executing it
oFor humans (neurotypicals), it will be easier to remember this
operation using mnemonics (expressions similar to natural oIt could be done manually (still quite error-prone) called hand-
languages) rather than the actual binary pattern assembling or with the help of computers with a special program
MOV R0,20H called the assembler
oThis considerably improves productivity, reduces errors and oSimilarly, disassembler converts machine code to assembly level
makes debugging much easier 3 program 4
Assembly Level Programming Sample 8086 Assembly program
oInstructions written in assembly usually will have two parts oFind the sum of 20H, 30H, 40H and 50H
MOV destination, source
mov ax, 20h ; Load 20h into AX
Opcode Operands
add ax, 30h ; Add 30h to AX
oopcode (stands for operational code) corresponds to the add ax, 40h ; Add 40h to AX
operation the processor needs to carry out add ax, 50h ; Add 50h to AX AX now contains
oAnd the operations are carried out on operations the result (E0h)
oAgain, coming back to the definition of software as collection of oMachine code for the above program
code and data, opcodes corresponds to the code portion and B8 20 00 05 30 00 05 40 00 05 50 00
operands corresponds to the data portion 5 6
o Data addressing modes are used to access data o Copies one or more bytes from one register to another
MOV AX,BX
o They are classified as Copies 16-bit data from BX register to AX register
→ Register addressing
MOV AL,BL
→ Immediate addressing Copies 8-bit data from BL register to AL register
→ Direct addressing
MOV CH,AL
→ Displacement addressing Copies 8-bit data from AL register to CH register
→ Register indirect addressing
MOV AL,BX
→ Base plus index addressing
Trying to move 16-bit data from BX to AL (8-bit register)
→ Register relative addressing May be no syntax error but should not use
9 10
→ Base relative plus index addressing Practically copies BX to AX → AH is also modified
oYou can move data between general purpose registers and oTransfers an immediate data (a constant byte or a word) to a
general-purpose registers and segment registers but you cannot register or memory
move data between segment registers
MOV AL,22
MOV AX,CX Copies data 22H to AL register (1 Byte data transfer)
MOV between general purpose register
MOV BX,49FE
MOV CS,BX Copies data 49FEH to BX register (2 Bytes (one word) data
MOV between general purpose and segment registers transfer)
oWhen moving data to register, the size of data (1-byte or 2-bytes) to oBut if you need to store 35H in memory address 2000H, the
copy assembler can understand from destination register size instruction will look exactly same
MOV AL,20;One byte transfer since AL is 1 byte
MOV AX,20;Two bytes transfer since AX is 2 bytes How to distinguish between them?
oBut when immediate data is moved to a memory location, assembler
cannot decide the data transfer size since using 8086 both 1-byte oWe need to add this information to the instruction
data and 2-byte data can be transferred to memory
MOV BYTE PTR [2000],35 ;move byte (1 byte)
oEg: We need to store 0035H in main memory starting from address
2000H (0035H will be stored as 35H in 2000H and 00H in 2001H MOV WORD PTR [2000],35 ;move word (2 bytes)
since Intel follows little endian architecture) MOV DWORD PTR [2000],35;move dword (4 bytes)
MOV [2000],35 13 14
Memory
Direct Addressing Displacement Addressing
oMoves a byte or word between memory and AL or AX register oMoves a byte or word between memory and register
oThe address is directly specified in the instruction oLooks exactly same as direct addressing in assembly, but instead of AX or
AL any other register is used
oThere is no support for memory-to-memory data transfer in oData is accessed with the help of a pointer register
8086 oMemory address of data is stored in a pointer register, then using
MOV [34F8],[23FE] ;illegal that pointer data is accessed
oWe can use BP, BX, DI and SI as pointer registers
oFirst copy from memory to register and then register to memory oEg: Assume you need to copy data from address 1000 and 1001 to
MOV AL,[23FE] AX register
MOV [34F8],AL oWe can use BX register as pointer
MOV BX,1000 ;store address in pointer
MOV AX,[BX] ;using pointer, access data
19 20
Register Indirect Addressing Base Plus Index Addressing
oInstructions such as oSimilar to register indirect addressing, but uses two registers (one
MOV [DI],10 base and one index) to calculate the physical address
also creates ambiguity regarding size of data (whether 1-byte or 2- oCan use BP or BX as base registers
bytes) oCan use SI or DI as index registers
oWill have to use size specification MOV DX,[BX+SI]
MOV byte ptr [DI],10 ;move 1 byte
oMemory offset address here = BX+SI
MOV word ptr [DI],10 ;move 1 word
oThis style of addressing is very helpful in accessing array elements
MOV dword ptr [DI],10 ;move 1 dword
by storing the array start address in a base address and using an
oThe qualifiers byte ptr, word ptr etc. are assembler directives, index register to specify index number of array element
which help assembler to choose the proper machine code
21 22
oLike base+index, but instead of specifying the offset in a register, it is oCombination of base+index and register relative
specified as a 16-bit signed number oAddress is specified by a base register (BX or BP), index register (SI
or DI) and a 16-bit signed constant displacement
oBP,BX,SI or DI can be used to store the base address
MOV AX,[BP+100] MOV AX,[BX+SI+100]
MOV BL,[BX-200]
MOV CX,[SI+2000] oHere memory offset address will be BX+SI+100
MOV CL,[DI+305]
25
Background
3 4
How to Segment? 8086 Programming Model Cont..
oThe idea is not to directly use the addresses specified in the →Contains the upper 16-bits of
program the starting address of a
Instruction Pointer (IP)(16) memory segment (partition)
oInstead use those addresses as an offset from a base address
Code Segment (CS)(16) →In 8086 the size of a segment
oFor example, in the previous memory partitioning, we observe most is 64KB
significant nibble for code partition is always 0x1 and for the data Stack Segment (SS) (16)
2FFFFH 348A
348A0H
CS
8086 BIU has a dedicated Code segment
adder to find the physical
address. Using ALU for this 4489FH
Purpose would have had 50000H
significant effect on performance 5000
SS Stack Segment
5FFFFH
70000H
7000 Extra segment
ES
9
7FFFFH 10
Bottom of data segment
Memory
Caution!! Caution!!
oSize of an 8086-memory segment is always 64KB oWhat processor does is; it will only take 16-bits of offset for adding
oYou should be careful when you use addressing modes such as with segment register
base+index, register relative etc. to access data within the segment oIf offset contains more than 16-bits, it will drop the MS bits (upper
oEg: DS = 2000 → Segment starting address 20000, segment ending bits)
address 2FFFF, BX = E200 oFor previous example, total offset
MOV AX,[BX+1F2E] BX+1F2E = E200+1F2E = 1012E
oIf you blindly calculate physical address oSince 1012E contains 17 bits, MS bit is dropped and offset is taken
Physical Address = DS<<4+BX+1F2E = 3012E as 012E
oBut this address is not in this segment oThus, physical address is
DS<<4+012E = 2012E, which is with in the segment
15 oSimilar approach is taken if the final physical address calculated has 16
oEarlier computers were not capable to multi-tasking and were used oIdea is to use different code/data segments for the two programs
for executing a single program for a single user
mov ax,bx mov ax,cx
oWhen multi-tasking was introduced, it was necessary to keep more add ax,cx sub ax,cx
mov [bx],ax mov [bp],ax
than one program concurrently in the main memory ……….
……….
……… ………
oIt is very much possible that these multiple programs were written ………
………
assuming they will be stored in the main memory starting at the
same address (Eg: Address 0x0)
oIf segmentation were not there, multi-tasking is not possible here pgm1.asm pgm2.asm
since both cannot concurrently occupy same address oStore both programs at address 10000H and 20000H and store
oBut with the help of segmentation, multi-tasking is possible 1000H in CS while executing program1 and 2000H in CS while
17 18
executing program2
10000H 10000H
pgrm1 pgrm1
1000
CS 20000H CS 20000H
10000H
pgrm1
oSet of all instructions supported by a processor oData Movement instructions are used to transfer data between
oAny program written in any programming language needs to be registers, memory and I/O ports
ultimately converted to instructions from instruction set of that 1.MOV
processor to execute it Function: Copies data from a source to destination
oAll your word processing software, image editors, web browsers and Syntax: MOV destination, source
games are ultimately composed of these low-level instructions
Eg: MOV AX, BX ;copy data from Bx register to Ax
oWe use assemblers to convert assembly-level programs to binary
MOV [5000], AX ;copy data from Ax register to
representation of instructions and compilers to convert high-level
memory offset address 5000
language codes to binary instructions
MOV AL, [SI] ;copy one byte data pointed by
oBut your assemblers and compilers are also built using these
3 contents of ds:SI to AL register 4
instructions!!
Data Movement Instructions Data Movement Instructions
2.XCHG 3.LEA
Function: Exchanges the contents of two operands Function: Load Effective Address. Used to load a 16 bit register with
Syntax: XCHG destination, source the effective offset address
Eg: XCHG AX, BX ;swaps data between Ax and Bx Syntax: LEA 16-bit destination register, source
registers Eg: LEA BX, [SI+DI] ;store SI+DI in BX register
XCHG [5000], AX ;swaps data between Ax register o This instruction is widely used for initializing pointers
and memory offset address 5000 o Note that the destination should be always a 16-bit register
XCHG AL, [SI] ;swaps one byte data pointed by
contents of ds:SI and AL register
5 6
3.SUB 4.SBB
Function: Subtracts source operand from destination and stores the Function: Subtracts source operand and borrow flag bit from
result in the destination operand destination and stores the result in the destination operand
Syntax: ADD destination, source Syntax: SBB destination, source
Eg: SUB AX,BX ;subtracts BX register content from Eg: SBB AX,BX ;subtracts BX and borrow bit from Ax
Ax register and stores the result in Ax register register stores result in AX register
SUB AL,20 ;subtracts constant 20 from AL SBB AL,20 ;subtracts constant 20 and borrow bit
register and stores result in AL register from AL register and stores result in AL register
9 10
4.INC 5.DEC
Function: Increments (adds 1) to register or memory location Function: Decrements (subtracts 1) from register or memory location
Syntax: INC destination Syntax: DEC destination
o When incrementing memory content, size of data must be described o When incrementing memory content, size of data must be described
using the BYTE PTR, WORD PTR directives using the BYTE PTR, WORD PTR directives
oINC instruction doesn’t affect the carry flag bit oDEC instruction doesn’t affect the carry flag bit
6.CMP 7.MUL
Function: Compares two operands. Internally processor does a Function: Performs unsigned multiplication
subtraction Syntax: MUL source
Syntax: CMP destination, source o One implicit operand will be always AX or AL (depending on size of
o results are reflected in the flag register source) other could be memory or register but not immediate value
Condition Zero flag Carry flag o If MUL is used with 8-bit operands, the 16-bit product will be stored
destination==source 1 0 in AX register
destination>source 0 0
destination<source 0 1
o If MUL is used with 16-bit operands, the 32-bit product will be
stored in DX:AX register pair (DX upper 16 bits, AX lower 16 bits)
o A compare operation is usually followed by jump instruction
Eg: MUL BX
Eg: CMP AX,BX 13 14
9.DIV
8.IMUL
Function: Performs unsigned division
Function: Performs signed multiplication
Syntax: DIV source
Syntax: MUL source
o The dividend will be always AX register or DX:AX register pair and
o One implicit operand will be always AX or AL (depending on size of source operand acts as the divisor
source) other could be memory or register but not immediate value oDivisor could be memory or register but not immediate value
o If IMUL is used with 8-bit operands, the 16-bit product will be stored o If DIV is used with 8-bit source, the 8-bit quotient (AX/source) will be
in AX register stored in AL register and the 8-bit reminder (AL%source) in AH register
o If IMUL is used with 16-bit operands, the 32-bit product will be o If DIV is used with 16-bit source, the 16-bit quotient (DX:AX/source) will
stored in DX:AX register pair (DX upper 16 bits, AX lower 16 bits) be stored in AX register and 16-bit reminder (DX:AX%source) will be
Eg: IMUL BX stored in DX register
15 Eg: DIV BX 16
Arithmetic Instructions Program Control Instructions
10.IDIV
JUMP Group
Function: Performs signed division
Syntax: IDIV source o Allows the programmer to skip sections of a program and branch to
any part of the memory for the next instruction
o The dividend will be always AX register or DX:AX register pair and
source operand acts as the divisor oA conditional jump instruction allows decisions based upon
oDivisor could be memory or register but not immediate value numerical tests
o If IDIV is used with 8-bit source, the 8-bit quotient (AX/source) will be oResults of numerical tests are held in the flag bits, which are then
stored in AL register and the 8-bit reminder (AX%source) in AH register tested by conditional jump instructions
o If IDIV is used with 16-bit source, the 16-bit quotient (DX:AX/source) will oSyntax: JMP_Instruction label (address)
be stored in AX register and 16-bit reminder (DX:AX%source) will be
stored in DX register
Eg: IDIV BX 17 18
Eg: Add 5 1-byte data starting from memory 2000H oIn the example loop is a label
MOV CX,5 ;used as loop control oThey are used as a place holder for address
MOV AL,0 ;initialize accumulator to 0 oIt will be difficult to manually calculate the offset address for the
jump instruction
MOV BX,2000 ;Will use as memory pointer
oInstead, we use a label to represent that address
loop:
oDuring assembling, assembler will replace the label with the
ADD AL,[BX] corresponding address
INC BX
DEC CX
JNZ loop ;check loop variable became 0 23 24
Thank you any
questions
25
Stack Memory
0
oStack is a logical memory block allocated 2
001A 18
1234 1A
SP 5 6
XXXX 1C
oAssembly instruction used to call a subroutine is the call instruction oAssembly instruction used to return from a subroutine is the RET
o Eg: call myFunction instruction
oHere myFunction represents the starting address of the oA subroutine may have one or more RET instructions (similar to a
subroutine high-level language function having more than one return
statement)
oSo how program control goes to the subroutine is pretty straight
forward oYou should make sure in assembly the processor always
encounters an RET instruction
oThe starting address of the subroutine is loaded to the instruction
pointer (IP) oBut how the program flows comes back to the instruction after
CALL instruction since there are not return address specified with
the RET instruction?
15 16
oThat is where stack comes into picture
Stack and Subroutines Stack and Subroutines
main: add: 0 main: add: 0
100: mov ax,10 200: add ax,bx 2 100: mov ax,10 200: add ax,bx 2
103: mov bx,20 202: ret 4 103: mov bx,20 202: ret 4
106: call add 6 106: call add 6
109: mov cx,ax 8 109: mov cx,ax 8
A A
C C
XXXX E XXXX E
CX 10 CX 10
12 12
XXXX 100 Stack Memory 14 0010 100 Stack Memory 14
AX IP 16 AX IP 16
Stack and Subroutines Stack and subroutine arguments and return value
main: add: 0
100: mov ax,10 200: add ax,bx 2 oStack can be used as a method to pass arguments and return
103: mov bx,20 202: ret 4 values(s) from a subroutine
106: call add 6
oIn 8086 this is slightly tricky
109: mov cx,ax 8
A oBefore calling the subroutine, you can push the arguments to the
C stack
0030 E oInside the subroutine, top of the stack is popped and backedup
CX 10 (that is the return address)
12
0030 109 Stack Memory 14
oThen arguments are popped
AX IP 16 oAfter processing return values(s) are pushed and then the return
0020 001A 18 address
0109 1A
BX SP 27 oIn the main function( calling function) return values are popped 28
XXXX 1C
Stack and subroutine arguments and return value Stack and subroutine arguments and return value
main: add: 0
oThe following example uses a subroutine add to find the sum of 2 100: push 100 200: pop cx 2
XXXX 001C 18
1A
29 BX SP 30
XXXX 1C
Stack and subroutine arguments and return value Stack and subroutine arguments and return value
main: add: 0 main: add: 0
100: push 100 200: pop cx 2 100: push 100 200: pop cx 2
103: push 200 203: pop ax 4 103: push 200 203: pop ax 4
106: call add 206: pop bx 6 106: call add 206: pop bx 6
109: pop cx 209: add ax,bx 8 109: pop cx 209: add ax,bx 8
20b: push ax A 20b: push ax A
20e: push cx C 20e: push cx C
XXXX 211: ret E XXXX 211: ret E
CX 10 CX 10
12 12
XXXX 100 Stack Memory 14 XXXX 103 Stack Memory 14
AX IP 16 AX IP 16
Stack and subroutine arguments and return value Stack and subroutine arguments and return value
main: add: 0 main: add: 0
100: push 100 200: pop cx 2 100: push 100 200: pop cx 2
103: push 200 203: pop ax 4 103: push 200 203: pop ax 4
106: call add 206: pop bx 6 106: call add 206: pop bx 6
109: pop cx 209: add ax,bx 8 109: pop cx 209: add ax,bx 8
20b: push ax A 20b: push ax A
20e: push cx C 20e: push cx C
0109 211: ret E 0109 211: ret E
CX 10 CX 10
12 12
0200 203 Stack Memory 14 0200 206 Stack Memory 14
AX IP 0109 16 AX IP 0109 16
Stack and subroutine arguments and return value Stack and subroutine arguments and return value
main: add: 0 main: add: 0
100: push 100 200: pop cx 2 100: push 100 200: pop cx 2
103: push 200 203: pop ax 4 103: push 200 203: pop ax 4
106: call add 206: pop bx 6 106: call add 206: pop bx 6
109: pop cx 209: add ax,bx 8 109: pop cx 209: add ax,bx 8
20b: push ax A 20b: push ax A
20e: push cx C 20e: push cx C
0109 211: ret E 0109 211: ret E
CX 10 CX 10
12 12
0300 20e Stack Memory 14 0300 211 Stack Memory 14
AX IP 0109 16 AX IP 0109 16
Stack to restore register values Stack and subroutine arguments and return value
add: 0
oIt is possible that in subroutines you modify register values 100: mov ax,10 200: push ax 2
103: mov bx,20 201: pushf 4
oIt is also possible that different people write different subroutines 106: call add 202: add ax,bx 6
for the same program 109: mov cx,[1000] 204: mov [1000],ax 8
oHow do you make sure that you are not inadvertently modifying 208: popf A
209: pop ax C
register contents which are used in other subroutines?
XXXX 20a: ret E
oTo avoid this, a thumb rule is any register content you are CX 10
modifying within a subroutine should be restored before returning 12
0010 100 Stack Memory 14
from the subroutine
AX IP 16
oIn the following example, subroutine is modifying ax register, but is 18
XXXX 001C
restored before returning 1A
43 BX SP 44
XXXX 1C
Stack and subroutine arguments and return value Stack and subroutine arguments and return value
add: 0 add: 0
100: mov ax,10 200: push ax 2 100: mov ax,10 200: push ax 2
103: mov bx,20 201: pushf 4 103: mov bx,20 201: pushf 4
106: call add 202: add ax,bx 6 106: call add 202: add ax,bx 6
109: mov cx,[1000] 204: mov [1000],ax 8 109: mov cx,[1000] 204: mov [1000],ax 8
208: popf A 208: popf A
209: pop ax C 209: pop ax C
XXXX 20a: ret E XXXX 20a: ret E
CX 10 CX 10
12 12
0010 103 Stack Memory 14 0010 106 Stack Memory 14
AX IP 16 AX IP 16
Stack and subroutine arguments and return value Stack and subroutine arguments and return value
add: 0 add: 0
100: mov ax,10 200: push ax 2 100: mov ax,10 200: push ax 2
103: mov bx,20 201: pushf 4 103: mov bx,20 201: pushf 4
106: call add 202: add ax,bx 6 106: call add 202: add ax,bx 6
109: mov cx,[1000] 204: mov [1000],ax 8 109: mov cx,[1000] 204: mov [1000],ax 8
208: popf A 208: popf A
209: pop ax C 209: pop ax C
XXXX 20a: ret E XXXX 20a: ret E
CX 10 CX 10
12 12
0010 200 Stack Memory 14 0010 201 Stack Memory 14
AX IP 16 AX IP FlagReg 16
Stack and subroutine arguments and return value Stack and subroutine arguments and return value
add: 0 add: 0
100: mov ax,10 200: push ax 2 100: mov ax,10 200: push ax 2
103: mov bx,20 201: pushf 4 103: mov bx,20 201: pushf 4
106: call add 202: add ax,bx 6 106: call add 202: add ax,bx 6
109: mov cx,[1000] 204: mov [1000],ax 8 109: mov cx,[1000] 204: mov [1000],ax 8
208: popf A 208: popf A
209: pop ax C 209: pop ax C
XXXX 20a: ret E XXXX 20a: ret E
CX 10 CX 10
12 12
0030 204 Stack Memory 14 0030 204 Stack Memory 14
AX IP FlagReg 16 AX IP FlagReg 16
Stack and subroutine arguments and return value Stack and subroutine arguments and return value
add: 0 add: 0
100: mov ax,10 200: push ax 2 100: mov ax,10 200: push ax 2
103: mov bx,20 201: pushf 4 103: mov bx,20 201: pushf 4
106: call add 202: add ax,bx 6 106: call add 202: add ax,bx 6
109: mov cx,[1000] 204: mov [1000],ax 8 109: mov cx,[1000] 204: mov [1000],ax 8
208: popf A 208: popf A
209: pop ax C 209: pop ax C
XXXX 20a: ret E 0030 20a: ret E
CX 10 CX 10
12 12
0010 109 Stack Memory 14 0010 109 Stack Memory 14
AX IP FlagReg 16 AX IP FlagReg 16
oYou can see stack is a dynamic memory, it grows and shrinks oTo minimize the scenario, if you are using stack memory, it will be a
oIf you are not careful enough, it is possible that stack keeps good idea to initialize it to towards the end of the segment
growing and encroaches portions of memory where you are stored oMost 8086 systems initialize SP to 0xFFFE
other data/code
oThis could be catastrophic
oThis scenario is especially possible when you have recursive
subroutines
oEach time the subroutine is called, the return address is pushed to
the stack and if termination condition takes too long, stack overflow
may happen
57 58
59