0% found this document useful (0 votes)
11 views7 pages

LectureNotes 9

assembly branching

Uploaded by

amirentezari.ac
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views7 pages

LectureNotes 9

assembly branching

Uploaded by

amirentezari.ac
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

School of Mathematics, Statistics

and Computer Science

Machine and Assembly Language Lecturer: Mojtaba Rafiee

Branching

Spring ’24 Lecture 9 Scribe(s): Belal Hashmi

1 Relative Addressing

Inside the debugger the instruction is shown as JMP 0119 and the location 0119 contains the original
first instruction of the logic of our program. This jump is unconditional, it will always be taken. Now
looking at the opcode we see F21600 where F2 is the opcode and 1600 is the operand to it. 1600 is 0016
in proper word order. 0119 is not given as a parameter rather 0016 is given.

This is position relative addressing in contrast to absolute addressing. It is not telling the exact address
rather it is telling how much forward or backward to go from the current position of IP in the current
code segment. So the instruction means to add 0016 to the IP register. At the time of execution of the
first instruction at 0100 IP was pointing to the next instruction at 0103, so after adding 16 it became
0119, the desired target location. The mechanism is important to know, however all calculations in
this mechanism are done by the assembler and by the processor. We just use a label with the JMP
instruction and are ensured that the instruction at the target label will be the one to be executed.

2 Types of Jump

The three types of jump, near, short, and far, differ in the size of instruction and the range of memory
they can jump to with the smallest short form of two bytes and a range of just 256 bytes to the far form
of five bytes and a range covering the whole memory.

1
Figure 1

2.1 Near Jump

When the relative address stored with the instruction is in 16 bits as in the last example the jump is
called a near jump. Using a near jump we can jump anywhere within a segment. If we add a large
number it will wrap around to the lower part. A negative number actually is a large number and works
this way using the wraparound behavior.

2.2 Short Jump

If the offset is stored in a single byte as in 75F2 with the opcode 75 and operand F2, the jump is called
a short jump. F2 is added to IP as a signed byte. If the byte is negative the complement is negated
from IP otherwise the byte is added. Unconditional jumps can be short, near, and far. The far type is
yet to be discussed. Conditional jumps can only be short. A short jump can go +127 bytes ahead in
code and -128 bytes backwards and no more. This is the limitation of a byte in singed representation.

2.3 Far Jump

Far jump is not position relative but is absolute. Both segment and offset must be given to a far jump.
The previous two jumps were used to jump within a segment. Sometimes we may need to go from one
code segment to another, and near and short jumps cannot take us there. Far jump must be used and a
two byte segment and a two byte offset are given to it. It loads CS wit the segment part and IP with the
offset part. Execution therefore resumes from that location in physical memory. The three instructions
that have a far form are JMP, CALL, and RET, are related to program control. Far capability makes
intra segment control possible.

2
3 Sorting Example

Moving ahead from our example of adding numbers we progress to a program that can sort a list of
numbers using the tools that we have accumulated till now. Sorting can be ascending or descending like
if the largest number comes at the top, followed by a smaller number and so on till the smallest number
the sort will be called descending. The other order starting with the smallest number and ending at the
largest is called ascending sort. This is a common problem and many algorithms have been developed
to solve it. One simple algorithm is the bubble sort algorithm.

In this algorithm we compare consecutive numbers. If they are in required order e.g. if it is a descending
sort and the first is larger then the second, then we leave them as it is and if they are not in order,
we swap them. Then we do the same process for the next two numbers and so on till the last two are
compared and possibly swapped.

A complete iteration is called a pass over the array. We need N passes at least in the simplest algorithm
if N is the number of elements to be sorted. A finer algorithm is to check if any swap was done in this
pass and stop as soon as a pass goes without a swap. The array is now sorted as every pair of elements
is in order.

For example if our list of numbers is 60, 55, 45, and 58 and we want to sort them in ascending order, the
first comparison will be of 60 and 55 and as the order will be reversed to 55 and 60. The next comparison
will be of 60 and 45 and again the two will be swapped. The next comparison of 60 and 58 will also
cause a swap. At the end of first pass the numbers will be in order of 55, 45, 58, and 60. Observe that
the largest number has bubbled down to the bottom. Just like a bubble at bottom of water. In the
next pass 55 and 45 will be swapped. 55 and 58 will not be swapped and 58 and 60 will also not be
swapped. In the next pass there will be no swap as the elements are in order i.e. 45, 55, 58, and 60.
The passes will be stopped as the last pass did not cause any swap. The application of bubble sort on
these numbers is further explained with the following illustration.

3
Example 3.3
001 ; sorting a list of ten numbers using bubble sort
002 [org 0x0100]
003 jmp start
004
005 data: dw 60, 55, 45, 50, 40, 35, 25, 30, 10, 0
006 swap: db 0
007
008 start: mov bx, 0 ; initialize array index to zero
009 mov byte [swap], 0 ; rest swap flag to no swaps
010
011 loop1: mov ax, [data+bx] ; load number in ax
012 cmp ax, [data+bx+2] ; compare with next number
013 jbe noswap ; no swap if already in order
014
015 mov dx, [data+bx+2] ; load second element in dx
016 mov [data+bx+2], ax ; store first number in second
017 mov [data+bx], dx ; store second number in first
018 mov byte [swap], 1 ; flag that a swap has been done

4
019
020 noswap: add bx, 2 ; advance bx to next index
021 cmp bx, 18 ; are we at last index
022 jne loop1 ; if not compare next two
023
024 cmp byte [swap], 1 ; check if a swap has been done
025 je start ; if yes make another pass
026
027 mov ax, 0x4c00 ; terminate program
028 int 0x21
003 The jump instruction is placed to skip over data.
006 The swap flag can be stored in a register but as an example it is stored in memory
and also to extend the concept at a later stage.
011-012 One element is read in AX and it is compared with the next element because memory
to memory comparisons are not allowed.
013 If the JBE is changed to JB, not only the unnecessary swap on equal will be per-
formed, there will be a major algorithmic flaw due to a logical error as in the case of
equal elements the algorithm will never stop. JBE won’t swap in the case of equal
elements.
015-017 The swap is done using DX and AX registers in such a way that the values are
crossed. The code uses the information that one of the elements is already in the
AX register.
021 This time BX is compared with 18 instead of 20 even though the number of elements
is same. This is because we pick an element and compare it with the next element.
When we pick the 9th element we compare it with the next element and this is the
last comparison, since if we pick the 10th element we will compare it with the 11th
element and there is no 11th element in our case.
024-025 If a swap is done we repeat the whole process for possible more swaps.

Inside the debugger we observe that the JBE is changed to JNA due to the same reason as discussed
for JNE and JNZ. The passes change the data in the same manner as we presented in our illustration
above. If JBE in the code is changed to JAE the sort will change from ascending to descending. For
signed numbers we can use JLE and JGE respectively for ascending and descending sort.

5
To clarify the difference of signed and unsigned jumps we change the data array in the last program
to include some negative numbers as well. When JBE will be used on this data, i.e. with unsigned
interpretation of the data and an ascending sort, the negative numbers will come at the end after the
largest positive number. However JLE will bring the negative numbers at the very start of the list to
bring them in proper ascending order according to a signed interpretation, even though they are large
in magnitude. The data used is shown as below.

1 data: dw 60, 55, 45, 50, -40, -35, 25, 30, 10, 0

This data includes some signed numbers as well. The JBE instruction will treat this data as an unsigned
number and will cater only for the magnitude ignoring the sign. If the program is loaded in the debugger,
the numbers will appear in their hexadecimal equivalent. The two numbers -40 and -35 are especially
important as they are represented as FFD8 and FFDD. This data is not telling whether it is signed or
unsigned. Our interpretation will decide whether it is a very large unsigned number or a signed number
in two’s complement form.

If the sorting algorithm is applied on the above data with JBE as the comparison instruction to sort in
ascending order with unsigned interpretation, observe the comparisons of the two numbers FFD8 and
FFDD. For example it will decide that FFDD > FFD8 since the first is larger in magnitude. At the end
of sorting FFDD will be at the end of the list being declared the largest number and FFD8 will precede
it to be the second largest.

If however the comparison instruction is changed to JLE and sorting is done on the same data it works
similarly except on the two numbers FFDD and FFD8. This time JLE declares them to be smaller than
every other number and also declares FFDD < FFD8. At the end of sorting, FFDD is declared to be the
smallest number followed by FFD8 and then 0000. This is in contrast to the last example where JBE
was used. This happened because JLE interpreted our data as signed numbers, and as a signed number
FFDD has its sign bit on signaling that it is a negative number in two’s complement form which is
smaller than 0000 and every positive number. However JBE did not give any significance to the sign bit
and included it in the magnitude. Therefore it declared the negative numbers to be the largest numbers.

If the required interpretation was of signed numbers the result produced by JLE is correct and if the
required interpretation was of unsigned numbers the result produced by JBE is correct. This is the very
difference between signed and unsigned integers in higher level languages, where the compiler takes the
responsibility of making the appropriate jump depending on the type of integer used. But it is only at
this level that we can understand the actual mechanism going on. In assembly language, use of proper
jump is the responsibility of the programmer, to convey the intentions to use the data as signed or as

6
unsigned.

The remaining possibilities of signed descending sort and unsigned descending sort can be done on the
same lines and are left as an exercise. Other conditional jumps work in the same manner and can be
studied from the reference at the end. Several will be discussed in more detail when they are used in
subsequent chapters.

4 Exercises

1. Which registers are changed by the CMP instruction?

2. What are the different types of jumps available? Describe position relative addressing.

3. If AX=8FFF and BX=0FFF and “cmp ax, bx” is executed, which of the following jumps will be
taken? Each part is independent of others. Also give the value of Z, S, and C flags.

a. jg greater

b. jl smaller

c. ja above

d. jb below

4. Write a program to find the maximum number and the minimum number from an array of ten
numbers.

5. Write a program to search a particular element from an array using binary search. If the element
is found set AX to one and otherwise to zero.

6. Write a program to calculate the factorial of a number where factorial is defined as:

factorial(x) = x ∗ (x − 1) ∗ (x − 2) ∗ ... ∗ 1

factorial(0) = 1

You might also like