100% found this document useful (1 vote)
128 views

COAL Lab#05

1) The document discusses different types of data addressing modes in assembly language including register, immediate, direct memory, and various forms of indirect memory addressing such as register indirect, based, indexed, and based-indexed. 2) Indirect memory addressing allows addressing of arrays and data structures by using a register as a pointer to memory locations. It specifies the memory address as [BaseReg + IndexReg * Scale + Disp]. 3) The IA-32 architecture supports both 32-bit and 16-bit addressing modes, with 16-bit modes originating in the 8086 processor which only had 16-bit registers. 16-bit modes use BX and BP as base registers.

Uploaded by

Tasawar Ahmed
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
128 views

COAL Lab#05

1) The document discusses different types of data addressing modes in assembly language including register, immediate, direct memory, and various forms of indirect memory addressing such as register indirect, based, indexed, and based-indexed. 2) Indirect memory addressing allows addressing of arrays and data structures by using a register as a pointer to memory locations. It specifies the memory address as [BaseReg + IndexReg * Scale + Disp]. 3) The IA-32 architecture supports both 32-bit and 16-bit addressing modes, with 16-bit modes originating in the 8086 processor which only had 16-bit registers. 16-bit modes use BX and BP as base registers.

Uploaded by

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

Lab 4: Basic Instructions and Addressing Modes

Contents
4.1. Data Transfer Instructions
4.2. Addition and Subtraction
4.3. Data Addressing Modes
4.4. LOOP Instruction
4.5. Copying a String
4.6. Summing an Array of Integers

4.1 Data Transfer Instructions


Data transfer instructions move data between registers or between registers and memory.
These instructions are briefly described below. For more details, refer to the lecture notes or
your textbook. The following program demonstrates the MOV, MOVZX, MOVSX, and
XCHG instructions:
MOV destination, source Move source to destination.
MOVZX destination, source Move source to destination with zero extension.
MOVSX destination, source Move source to destination with sign extension.
XCHG destination, source Exchange source with destination.

TITLE Data Transfer Examples (File: moves.asm)


; Demonstration of MOV, MOVZX, MOVSX, and XCHG

.686
.MODEL flat, stdcall
.STACK
INCLUDE Irvine32.inc
.data var1
WORD 1000h var2
WORD 2000h
.code
main PROC
; Demonstrating MOV and MOVZX
mov ax, 0A69Bh movzx
bx, al movzx ecx,ah
movzx edx,ax

; Demonstrating MOVSX
movsx bx, al movsx
ecx,ah movsx
edx,ax

; Demonstrating XCHG
xchg ax,var1 xchg
ax,var2 xchg ax,var1

exit
main ENDP END
main
4.1.1 Lab Work: Assemble and Link moves.asm
Open file moves.asm and assemble and link the file. You can use the make32 batch file from
the command prompt. And then we linked/assembled the file debugging with the keyword
windbg –QY–G moves.exe. which is showing down below:

4.1.2 Lab Work: Trace the Execution of Program moves.exe


1.Now we run the Windows debugger to trace the execution of the above program. First we
can see all values of each registers before executing the main PROC which is showing down
below:
2. Now let’s see the values of each registers After the execution of main PROC one-by-one: ;
Demonstrating MOV and MOVZX Now we can see the value of ax after execution is ax=
0xa69b.

3. Now Demonstrating MOVSX .The value of bx in hex after execution is bx= 0xff9b.

4. Now Demonstrating XCHG .Now we can see the changing in var1, ax, al and a and also
we can see the changing in var2.
Open the Watch window to view the var1 and var2 variables. You can also watch registers
under the Watch window by typing their names preceded with the @ symbol as shown below.
Observe that the type of registers is unsigned int and the value is shown in hexadecimal. You
can change the type of a register to char, short, or int (depending on its size), to see its value
as a signed decimal.
5. Now we can see the changing in var1, ax, al and ah.
MOV and MOVZX
1) al, ah (hex) = 0x9b, 0xa6 2) bx (hex) = 0x9b

3) ecx (hex) = 0xa6 4) edx (hex) = 0xa69b


MOVSX

5) bx (hex) = 0xff9b

6) ecx (hex) = 0xffffffa6 7) edx (hex) = 0xffffa69b


XCHG
8) ax (hex) =0x1000 8) var1 (hex) = 0xa69b

9) ax (hex) = 0x2000 9) var2 (hex) = 0x1000

10) ax (hex) = 0xa69b 10) var1 (hex) = 0x2000


4.2 Addition and Subtraction
Integer addition and subtraction are two of the most fundamental operations that a processor
can perform. In the following Program, you will learn about the INC, DEC, ADD, SUB, and
NEG instructions. You will also learn about the flags affected by these arithmetic
instructions:
INC destination Increment destination by 1.
DEC destination Decrement destination by 1.
ADD destination, source Add source to destination.
SUB destination, source Subtract source from destination.
NEG destination Negate destination by computing 2's complement.
CF Carry Flag: set if unsigned result is out of range.
OF Overflow Flag: set if signed result is out of range.
SF Sign Flag: set if sign bit of result is negative (or 1).
ZF Zero Flag: set if result is zero (all bits are zero).
PF Parity Flag: set if low byte of result has even number of 1’s.
The ADD, SUB, and NEG instructions affect all the above flags. The INC and DEC
instructions also affect the above flags, except that the carry flag is not modified. For more
details about these instructions and flags, refer to the lecture notes or your textbook.

TITLE Simple Arithmetic (SimpleArith.asm)


.686
.MODEL flat, stdcall
.STACK
INCLUDE Irvine32.inc
.data ; No data
.code
main PROC
; ADD
mov eax, 91ab0748h
mov ebx, 3f54f8f2h
add eax, ebx

; SUB
mov eax, 91ab0748h
sub eax, ebx

; NEG
mov eax, 91ab0748h
neg eax

; INC
clc ; clear carry flag to show that it is not affected mov
eax,7fffffffh
inc eax

; DEC
mov eax,0
dec eax
exit
main ENDP END
main

4.2.1 Lab Work: Assemble and Link SimpleArith.asm


1. Now we run the Windows debugger to trace the execution of the above program. First we
can see all values of each registers before executing the main PROC which is showing down
below:
We can see the value of eax after adding the value of ebx and eax = d100003a.

2. SUB
We can see the value of eax after execution is eax=91ab0748.
3. ; INC Now we can see the value of eax after execution is eax= 7ffffff.

4. Now we can see the value of eax after decrement eax= ffffffff.
4.2.2 Lab Work: Trace the Execution of SimpleArith.exe
First, guess the values of the eax register (in hexadecimal) and the cf, of, sf, zf, and pf flags
after executing the add, sub, neg, inc, and dec instructions. Write these values below:
CF= OF= SF= ZF= PF=
1) EAX after ADD (hex) = d100003a
0 0 1 0 1
CF= OF= SF= ZF= PF=
2) EAX after SUB (hex) = 52560e56
0 1 0 0 1
CF= OF= SF= ZF= PF=
3) EAX after NEG (hex) = 6e54f8b8
1 0 0 0 1
CF= OF= SF= ZF= PF=
4) EAX after INC (hex) = 80000000
0 1 1 0 1
CF= OF= SF= ZF= PF=
5) EAX after DEC (hex) = ffffffff
0 0 1 0 1
Run the 32-bit Windows Debugger. Open the source file SimpleArith.asm from the File menu
if it is not already opened. Watch the registers by selecting Registers from the View menu.
Have the registers eax, ebx and the flags cf, of, sf, zf, and pf on top of the list. Place the
cursor at the beginning of main procedure and press F7 to start debugging it. Press F10 to
step through the execution of the program. Watch the changes in the registers and flags.

4.3 Data Addressing Modes


The assembly language instructions require the specification of the location of data for source
and destination operands. The specification of the location of data is called the data
addressing mode. It can be classified as shown in the following diagram:
Addressing Modes

Register Memory Immediate

Direct Indirect

Register Based Indexed Based-


Indirect Indexed
Register addressing is when a register is used to specify the source or destination of an
operand. This is the most efficient addressing mode because registers are implemented inside
the processor and their access is very fast. Immediate addressing is when an immediate
value (a constant) is used for a source operand. It cannot be used to specify a destination
operand. The immediate constant is part of the instruction itself.
Memory addressing is used to specify the address of the source and destination operands
located in memory. This is the most detailed and interesting addressing mode. It can be
divided into direct and indirect memory addressing. Direct memory addressing is when the
address of a memory operand is specified directly by name. For example: mov sum, eax
; sum is a variable in memory
Direct memory addressing is useful for accessing simple variables in memory, but it is useless
for addressing arrays or data structures. To address the elements of an array, we need to use a
register as a pointer to the array elements. This is called indirect memory addressing. It can
be further classified into register indirect, based, indexed, and basedindexed, depending on
how the address of the memory operand is specified. In general, a memory address can be
specified as follows:
Address = [BaseReg + IndexReg * Scale + Disp]
This is the most general indirect memory addressing called based-indexed, because it
combines a base register with an index register and a displacement. The other indirect
memory addressing modes: register indirect, based, and indexed are simpler.

Register Indirect Addressing: Address = [Reg]


Based Addressing: Address = [BaseReg + Disp]
Indexed Addressing: Address = [IndexReg * Scale + Disp]
The IA-32 processor architecture supports 32-bit addressing as well as 16-bit addressing.
16bit addressing modes originated in the 8086 processor, which supports only 16-bit
registers. The 16-bit addressing modes use BX and BP for the base register and SI and DI for
the index register. No scale factor is allowed, and displacements are limited to 16 bits.
With the advent of the IA-32 processor architecture, registers were extended from 16 bits to
32 bits. This enabled 32-bit addressing modes in addition to 16-bit addressing. Any 32-bit
general-purpose register (EAX, EBX, ECX, EDX, ESI, EDI, EBP, or ESP) can be used as a
base register. Any general-purpose register, with the exception of ESP can be used as an index
register. A scale factor of 1, 2, 4, or 8 is added to indexed-addressing, and displacements are
extended to 32-bits.
The differences between 16-bit and 32-bit addressing modes are summarized below:
16-bit Addressing 32-bit Addressing
Base Register BX, BP EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP
Index Register SI, DI EAX, EBX, ECX, EDX, ESI, EDI, EBP
Scale Factor None 1, 2, 4, 8
Displacement 0, 8, 16 bits 0, 8, 32 bits

4.3.1 Examples on 32-bit Addressing Modes


The following program demonstrates 32-bit memory addressing modes and the LEA (Load
Effective Address) instruction. The LEA instruction moves the address, rather than the value,
of a source operand into destination.
LEA destination, source Load Effective Address of source into destination
This is similar to moving the OFFSET of a variable. For example,
lea eax, variable is simlar to mov eax, OFFSET variable

The LEA instruction provides more flexibility in terms of computing complex addresses at
runtime. However, the OFFSET operator is used to determine the address of named variables
at assembly-time.

TITLE Memory Addressing Examples (File: addressing.asm)


.686
.MODEL flat, stdcall
.STACK
INCLUDE Irvine32.inc
.data
arrayB BYTE "COE 205",0 arrayW
WORD 100h,200h,300h, 400h arrayD
DWORD 01234567h,89ABCDEFh
.code
main PROC
; Direct Memory Addressing
mov al, arrayB ; same as [arrayB]
mov ah, arrayB[5] ; same as [arrayB+5]
mov bx, arrayW[2] ; same as [arrayW+2]
mov ecx,[arrayD] ; same as arrayD mov
edx,[arrayD+2] ; same as arrayD[2]

; Register Indirect Addressing


mov ecx, OFFSET arrayB + 3 mov
edx, OFFSET arrayW + 1
mov bx, [ecx] ; address in [ecx]
mov al, [edx] ; address in [edx]

; Based Addressing
mov edx, 4 mov al,
arrayB[edx] mov bx,
arrayW[edx] mov
ecx,arrayD[edx]
; Scaled Indexed Addressing
mov esi, 1 mov
arrayB[esi*2], 'S' mov
arrayW[esi*2], 102h mov
arrayD[esi*4], 0

; Load Effective Address (LEA)


lea eax, arrayB
lea ebx,[eax + LENGTHOF arrayB]
lea ecx,[ebx + esi*8] lea edx,
arrayD exit main ENDP END main
4.3.2 Lab Work: Assemble and Link ‘addressing.asm’ 4.3.3 Lab Work: Trace the
Execution of Program ‘addressing.exe’
First, guess the values of the registers and memory variables in program addressing.asm.
Write your answers in hexadecimal in the specified boxes after the execution of each
instruction. For characters, show the character symbol as well as its code in hexadecimal.
Run the Windows Debugger. Open the source file addressing.asm from the File menu if it is
not already opened. Watch the registers and memory by selecting them in the View menu. In
the Memory window, write the name of the first variable arrayB in the Virtual address box.
You may resize the Memory window so that exactly 16 bytes are displayed on each line.
Place the cursor at the beginning of main procedure and press F7. Press F10 to step through
the execution of the program. Watch the changes in the registers and memory.
1.

2.
3.

4.
5.

Direct Memory Addressing


1) al = 43 2) ah = 30 3) bx = 200

4) ecx = 1234567 5) edx = cdef0123

Register Indirect Addressing

6) ecx = 404003 7) edx = 404009


8) bx = 3220 9) al = 1

Based Addressing

11) al = 32 12) bx = 300 13) ecx = 89abcdef


Scaled Indexed Addressing – show the address and byte values in memory
15) arrayB address 66 c7 04 75 08 40 40 02

16) arrayW address C7 04 b5 10 40 40 8d 05

17) arrayD address 8d 05 40 40 8d 58 08 8d

Load Effective Address (LEA)


18) eax = 404000 19) ebx = 404008

20) ecx = 404010 21) edx = 404010

4.4 LOOP Instruction


The LOOP instruction provides a simple way to repeat a block of statements a specific
number of times. It uses ECX as a counter, which is decremented each time the loop repeats.
The execution of the LOOP instruction involves two steps: First, it subtracts 1 from ECX. If
ECX is not equal to zero, a jump is taken to the label (start of the loop). Otherwise, the loop
terminates and the next instruction is executed.
LOOP label Decrement ECX and Jump to label if ECX ≠ 0

4.5 Copying a String


Study the following program:

TITLE Copying a String (File: CopyStr.asm)


; Demonstrates LOOP instruction and array indexing

.686
.MODEL flat, stdcall
.STACK

INCLUDE Irvine32.inc
.data
source BYTE "This is the source string",0 target
BYTE SIZEOF source DUP(0)

.code main
PROC
mov esi, 0 ; used to index source and target
mov ecx, SIZEOF source ; loop counter
L1:
mov al, source[esi] ; get a character from source
mov target[esi], al ; store it in the target
inc esi ; increment index
loop L1 ; repeat for entire string

exit
main ENDP END
main

What is the value of the target string in memory after finishing the execution of loop
L1?

Answer: After the execution of loop L1, the value of the target string in memory will be a
copy of the source string, which is "Twinkle twinkle little star".

What is the number of iterations for loop L1?

Answer: The number of iterations for loop L1 is determined by the SIZEOF source
instruction. In this case, the source string is "Twinkle twinkle little star" followed by a null
terminator (0).

Therefore, the number of iterations for loop L1 is 30 (the number of characters in the source
string) + 1 (for the null terminator) = 31.

4.5.1 Lab Work: Assemble and Link CopyStr.asm 4.5.2 Lab Work: Trace the
Execution of CopyStr.exe
1.First of all we go in the loop.

2.Then we press F8 to execute line by line loop.


3.Then it will add first string variable.

4.So we can execute many time to copy the complete string.


s

4.6 Summing an Array of Integers


Program SumArray.asm uses register esi as a pointer to intarray. Register-indirect addressing
is used to access the elements of intarray.
TITLE Summing an Array of Signed Words (File: SumArray.asm)
; Register-Indirect memory addressing is used

.686
.MODEL flat, stdcall
.STACK

INCLUDE Irvine32.inc
.data
intarray SWORD 5,7,-3,100,0,-9, 10 DUP(-999) sum
SWORD ?
.code
main PROC
mov esi,OFFSET intarray ; esi = pointer to intarray
mov ecx,LENGTHOF intarray ; ecx = loop counter
mov ax,0 ; zero the accumulator
L1:
add ax,[esi] ; register esi is a pointer add
esi,TYPE intarray ; point to next integer
loop L1 ; repeat until ECX = 0

mov sum, ax
exit
main ENDP END
main
4.6.1 Lab Work: Assemble, Link, and Trace Program Execution
Open file SumArray.asm and assemble and link the file. Now run the Windows debugger to
trace the execution of the above program. You need to view the registers esi, ecx, and ax. Add
also a watch for the sum variable.
1.

2.

3.
4.

Q. What is the value of sum (in decimal) at the end of the program?

Answer: Value of sum (in decimal) at the end of the program:

Sum = 5 + 7 + (-3) + 100 + 0 + (-9) + 10 * (-999) = -973.

Therefore, the value of sum is -973.

Q. How many iterations was loop L1 repeated?

Answer:
LENGTHOF intarray is the number of elements in intarray, which is 13.

So, loop L1 was repeated 13 times

Q. Assuming the initial value of ESI is 404000h before starting loop L1, what is the
final value of ESI (in hex) after finishing loop L1?

Answer: Assuming the initial value of ESI is 404000h, and each element in intarray is of
type SWORD (2 bytes), the final value of ESI can be calculated as follows:

Initial ESI: 404000h

Increment per iteration: TYPE intarray (2 bytes) * LENGTHOF intarray (13)

Final ESI = 404000h + (2 * 13) = 404026h.

Review Questions
1. For each of the following, write the destination register value (in hexadecimal) if the
instruction is valid. Otherwise, indicate that the instruction is invalid. Assume that var1 is
at virtual address 404000h.
var1 SBYTE -4, 2
var2 WORD 1000h, 2000h,3000h
var3 DWORD 1, 2, 3, 4, 5
a. mov ax, var1 Invalid because var1 is at a virtual
address (404000h) and not a register.
b. movzx ax, var1 Invalid because movzx requires a
register or memory operand as the source, and var1 is at a
virtual address.
c. movsx eax, var1 Invalid for the same reason as b
d. mov ax, var2[2] Valid. It moves the value at the third
element (index 2) of the array var2 into the ax register.
e. mov bx, var3 Invalid because var3 is an array, and
you can't directly move an array into a register.
f. mov edx, [var3+4] Valid. It moves the double-word at the
address var3 + 4 into the edx register.
g. lea esi, var2 Valid. It loads the effective address
(address of the first element) of the array var2 into the
esi register.
h. mov al, [esi] Valid. It moves the byte at the address
stored in esi into the al register.
i. mov ax, [esi] Valid. It moves the word at the address
stored in esi into the ax register.
j. mov eax, [esi] Valid. It moves the double-word at the
address stored in esi into the eax register.
k. inc [esi] Valid. It increments the value at the
address stored in esi.

2. Is it possible to set the Overflow flag if you add a positive to a negative integer?
Yes
3. Is it possible for the NEG instruction to set the Overflow flag?
Yes
4. Is it possible for both the Sign and Zero flags to be set at the same time?
No
5. Can any 16-bit general-purpose register be used for indirect addressing?
Yes
6. Can any 32-bit general-purpose register be used for indirect addressing?
Yes

Programming Exercises
1. Write a program that does the following:
• Use the ADD and SUB instructions to set and clear the Carry flag.
• Use the ADD and SUB instructions to set and clear the Zero and Sign flags.
• Use the ADD and SUB instruction to set and clear the Overflow flag.
• Use the ADD instruction to set and clear both the Carry and Overflow flags.
Trace program execution and Explain why the flags are affected by each instruction.
2. Write a program that uses a loop to calculate the first ten values in the Fibonacci number
sequence {1, 1, 2, 3, 5, 8, 13, 21, 34, 55}. Place each value in the EAX register inside the
loop, and trace it with the Windows debugger.
TITLE Fibonacci Series (File: fibonacci.asm)

.686
.MODEL flat, stdcall
.STACK
INCLUDE Irvine32.inc
.data
fib DWORD 10 DUP(0)

.code
main PROC
mov ecx, 10 ; Number of Fibonacci values to calculate
mov ebx, 1 ; First Fibonacci number
mov esi, 1 ; Second Fibonacci number

mov eax, ebx


mov fib[0], eax ; Store the first Fibonacci number

; Loop to calculate the Fibonacci sequence


mov ecx, 8 ; Loop for the next 8 values
mov edi, OFFSET fib + 4 ; Point to the next element in fib array

Loop1:
add eax, esi ; Calculate the next Fibonacci number
mov esi, ebx ; Update the second Fibonacci number
mov ebx, eax ; Update the first Fibonacci number

; Store the Fibonacci number in the array


mov [edi], eax

add edi, 4 ; Move to the next element in fib array


loop Loop1 ; Repeat the loop

; Exit the program


invoke ExitProcess, 0

main ENDP
END main
3. Modify Program SumArray.asm to use the register esi as an index to intarray with a scale
factor of 2, instead of a pointer. Trace it with the Windows debugger.
4. Modify Program CopyStr.asm to use the register esi as a pointer (indirect addressing),
instead of an index, to copy the characters from source to target, but in reverse order.

You might also like