Pflow

advertisement
Program Flow – Jumps and Calls
@ P. Klimo
5/11/04
Program Flow – Jumps and Calls
1.
Unconditional JUMPS :
Program Flow Chart with Unconditional Jumps
JUMPS:
Type
Mnemonic
Operand
Advantages
Disadvantages
Re-locatable Code
Relative
JUMPR
Displacement
Very Fast
Small jump range
Yes
Intra-Segment
JUMP
Offset
Faster execution
Current Segment
Yes
Inter-Segment
JUMPF
Segment : Offset
Can jump anywhere
Slower execution
No
Relative Addressing:



The jump address is specified by relative (positive or negative) address offset
which is added to the current content of the program counter to give the
destination address.
As the current content of program counter is the address of the instruction
following the current jump instruction, the relative offset is calculated as
follows:
Relative Offset = Destination Address – Next Instruction Address
Positive offset signifies forward jump and negative offset means backward
jump.
1
Program Flow – Jumps and Calls
@ P. Klimo
5/11/04
Example of Absolute Jump:
Using DEBUG, load the value 0FFFFh into CS and 0 into IP. Then dump memory at
FFFF:0000:
You will see that the “start up” memory location FFFF0 contains bytes such as
FFFF:0000
EA 5B E0 00 F0
Here EA is the opcode for the absolute (inter-segment) jump JMPF. The next two
bytes represent the segment offset 00E0 and the last two bytes the code segment F000:
JMPF F000:00E0
In MASM there is only one mnemonic for jump. The Inter-Segment jump is
flagged out by the assembler directive FAR as shown in this extract:
EXTERN label_1 : FAR
label_2
; defines a label with property FAR i.e. carries
;absolute (segment : offset) address.
; the specifier EXTERN informs assembler that
; the label is defined in another file (module).
JUMP label_2
………
JUMP label_1
; translates to a near jump
; translates to a far jump at
Example of Relative Jump:
Assume you see bytes at memory 300
0100:
EB 02 01 D8 A3 00 02 D8 …
In 8086 machine code
0100:
0102:
0104:
;
;
;
;
;
;
jmp 02
add AX, BX
mov [0200], AX
In MASM
.
org 0200
addr dw ( ?)
org 0100
jmp here
add AX,BX
here mov addr, AX
Note: The jump offset is calculated as starting from the instruction following the relative jump
instruction. This address is 00302 (the JMP is two bytes long ,i.e opcode and a one byte operand ).
The relative displacement is calculated:
Offset = 0304 – 0302 = 2

The length of relative jump is limited by the size of the operand
Example: 8086 CPU branch instructions have an 8 bit operand.
8 bit relative address allows max jumps across 27 memory locations
(i.e 127 forward and 128 backwards)
2
Program Flow – Jumps and Calls
2.
@ P. Klimo
5/11/04
Conditional Jumps (Branches)
Flow Diagram:
CONDITIONAL JUMPS (BRANCHES):
The execution of the branch depends on the current condition of the flags in the
flag register:
ZF
CF
SF
OF
PF
zero flag
carry flag
sign flag
overflow flag
parity flag
The seven ‘survival’ kit branch 8086 instructions are:
JZ
JNZ
General:
Jump if result was Zero
jump if result was Not Zero
JA
JB
For unsigned numbers:
Jump if result was Above zero
CF = ZF = 0
Jump if result Below zero
CF =1
JG
JL
For signed numbers:
Jump if result Greater than zero ZF=0 and SF=OF
Jump if result Less than zero
SF  OF
3
ZF set (ZF=1)
ZF not set (ZF=0)
Program Flow – Jumps and Calls
@ P. Klimo
5/11/04
ALL Branch instructions in 8086 use RELATIVE Addressing:
Example of Assembly Listing.
Var_I
My_loop:
DB
0Ah
MOV AX, Var_I
DEC AX
BNZ My_loop
MOV BX, AX
; Define the variable
; Copy the variable’s value into AX
; Decrement AX
; Branch if Not Zero to the label My_loop
Note : When the BNZ instruction ( Branch on Not Zero) starts executing, the CPU
checks the Zero flag in Flags Register. If this is not set, i.e. the result of the
previous instruction (DEC AX ) was not zero, the program counter is set to
point to the address location defined by the label My_loop. If the zero flag has
been set then the program counter is pointed towards the instruction following
the BNZ instruction. Thus the final instruction MOV BX, AX always copies a
zero into BX.
The above listing does not change the value of the variable Var_I.
Problem:
Revise the above listing so that the value of the variable is decremented by
each loop until it becomes zero. (Hint: Decrement the variable in memory
location directly by using instruction DEC Var_I. ).
Question:
Which of the two differently coded loops will run faster and why ?
3.
Subroutines (Procedures):
Example :
The following example converts the ASCII upper case letter codes to the lower case
ones. The algorithm is based on the fact that the lower case letters a, b, c …z have
ASCII codes which are 20h more than their upper case equivalents A, B, C … Z.
Letter :
DB ‘A’
Convert:
MOV AL, Letter
ADD AL, 20h
MOV Letter, AL
; define a byte in memory and initiate it to the ASCII
; code for letter A.
; Convert from upper to lower case
; and replace in memory location with ‘a’
Repeated use of this extract would require to repeat entering the same machine code
into memory thus eventually exhausting all the available program memory!!!
Instead, we can place one copy of the conversion routine into a memory segment
starting say at a certain location Convert and each time we want to run it from the
calling program we execute the CALL instruction which will set the PC to the routine
and after running it, returns to the calling program at the place it “ took off”:
4
Program Flow – Jumps and Calls
@ P. Klimo
5/11/04
Observe that:
 There is only one copy of machine code for each subroutine
irrespective of how many times the subroutine is called. This saves
program memory.
 CALL instruction has to save the value of the Program Counter
before it branches to the subroutine.
 Before returning to the calling program the subroutine code has
to include a special Return from Subroutine instruction ( RET)
which will restore the value of the PC to the value which it held
before the jump to the subroutine was taken.
5
Program Flow – Jumps and Calls
@ P. Klimo
5/11/04
Question:
Where does the CALL instruction save the value of the PC ??
Answer:
On the Memory Stack.
Question:
What is a Stack ?
Answer :
Stack is a one dimensional data storage structure characterised by
the Last in First Out (LIFO) behaviour.
Example of LIFO is a stack of plates in a cafeteria. We can add plates
or take away plates to or from the TOP f the STACK.
MEMORY Stack.
6
Program Flow – Jumps and Calls
@ P. Klimo
5/11/04

There is always one current memory location identified as The TOP of the
Stack. This is pointed to by the Stack Pointer (SP) register.

There are two operation associated with a Stack:
1.
PUSH AX increments the SP and copies the AX data at the newly created
location at the top of the stack.
2.
POP AX copies the data from the top of the stack into AX and then
decrements the SP to create a new top of the stack.
NOTE:


Data locations above the current top of the stack do not hold valid data.
If stack growth or shrinks beyond the memory space reserved for stack any
PUSH operations will overwrite the adjacent memory and may cause the
program to crash.
Example: The previous Convert program written as a subroutine:
Letter :
DB ‘A’
Main:
CALL Convert
MOV BL, Letter;
…
…
MOV Letter, ‘B’
CALL Convert
…
…
END
Convert:
; Define a byte in memory and initiate it to the ASCII
; code for letter A.
; First call for the subroutine. When the subroutine returns
; the converted letter will be in memory location Letter.
; Do something else with the converted letter
; Do another letter
; Second call for the subroutine
MOV AL, Letter
ADD AL, 20h
MOV Letter, AL
RET
; First instruction of the subroutine takes the letter
; from the memory location Letter.
; Converts it from the upper to the lower case
; and replaces the memory location Letter with the
; newly converted letter.
; Return from subroutine
What does CALL do?:
(a)
(b)
Pushes the current value of IP onto stack
Loads IP (and CS) with address of subroutine
What does RET do?:
(a)
Pops the current top of stack into IP (and CS)
7
Program Flow – Jumps and Calls

@ P. Klimo
5/11/04
As with JUMP, there are two types of CALL 8086 instruction:
1. Near CALL (mnemonic CALL and corresponding RET) which has a
maximum range equal to the Intra-Segment JUMP instruction. The
operand is only the segment offset of the procedure. This type of
subroutine is re-locatable.
2. Far CALL (mnemonic CALLF and corresponding RETF) which has an
unlimited range, similar to the Inter-Segment JUMP instruction. The
operand is in the form segment:offset and the program containing Far
Call is not re-locatable.
Note: In MASM the same instruction CALL is used for both the Far and the
Near types of procedures. As with the JUMP, MASM needs the directive
syntax below to distinguish between the two.
<label>
<label>
PROCEDURE
…..
ENDP
FAR ; or NEAR

The subroutine may reside in another part of the program memory (e.g.
forming a part of a library of subroutines assembled in a different module(s),
called object files)

It is the responsibility of the Linker program to identify all subroutines
referred to in different modules (object files) and link their addresses to form
one executable file which can be run by the CPU.
An executable program is created by firstly assembling all modules
into object files and then linking all the object files to obtain one
executable file.
8
Program Flow – Jumps and Calls
Example:
@ P. Klimo
5/11/04
Subroutine and Branches in 8088/86
The Intra-Segment and Inter-Segment Mechanism.
Consider the following program extract:
010B
010D
0110
0110
0113
8B
E8
F4
F7
8B
C1
01 00
E3
D0
MOV AX,CX
CALL A_SUB
HLT
MUL BX
MOV DX, AX
.
.
RET
A_SUB:
0124 C3
Trace the effect of CALL and RET on the contents of IP, SP and the
stack.
Before
After
CALL 0001
IP
SP
01E1
01E2
01E3
01E4
010D
01E4
0111
01E2
??
??
??
??
??
10
01
??
RET
IP
SP
01E1
01E2
01E3
01E4
0125
01E2
0110
01E4
??
10
01
??
??
10
01
??
9
Program Flow – Jumps and Calls
@ P. Klimo
5/11/04
Commentary:
 By the time these instructions come to be executed the assembler
will have replaced the label A_SUB with one of two things:
1. If the subroutine with the first instruction labelled A_SUB is
stored within 0FFFF locations of the CALL instruction, then
the label A_SUB will be replaced by a 16 bit signed number.
This number specifies what will need to be added to the
contents of the IP (PC) register after execution of CALL has
begun in order for CS:IP to point to the instruction labelled
A_SUB. Thus in the above case the label in CALL A_SUB will
be replaced by 0001.
But this is not the only effect of CALL. It also pushes the 16
bit address offset of the instruction which follows CALL onto
the stack. The execution of the RET instruction simply pops
this value back to the IP.
This type of CALL and RET is known as intra-segment
instructions.
2. If the first instruction the subroutine is more than 0FFFF
locations apart, the inter-segment form of CALL (CALLF)
and RET (RETF) must be used. Now the assembler replaces
the A_SUB label with a 4 byte number defining the absolute
address of the first instruction (two bytes for CS and two
bytes for IP). Similarly, the CALL instruction updates the
values of the CS and IP accordingly and places on stack a four
byte number representing the absolute address of the
instruction following the CALL. When the RET instruction
executes it pops these four bytes of the address to the CS and
the IP.
10
Program Flow – Jumps and Calls
@ P. Klimo
5/11/04
Exercise: Re-Entrant Subroutine
Re-entrant subroutine is the one that calls itself.
What will be the content of the memory locations
5030h to 5040h after the following program extract?
Assume initially the content of SP is 5040h.
Memory Dump
4000:
B0 02
4002:
FF 16 10 40
4006:
CD 20
start
MOV AL,2
CALL alpha
stop
INT 20h
........
; Subroutine alpha
alpha
MOV BL,56h
4010:
B3 56
4012:
FF C8
DEC AL
4014:
74 04
JZ fini
4016:
FF 16 10 40
401A:
C3
CALL alpha
fini
11
RET
Download