COAL v2.0
COAL v2.0
INDEX
Lab Obtained
Date Particulars Instructor Marks
Signature
Lab 1: Introduction to Irvine Library and installation
Lab 12: Stack Memory & its Parameters & Advance Procedures
This Lab shows you how to set up Visual Studio 2010 (including the Express version) to
work with Microsoft MASM.
Using Visual Studio Express? You must do the following in order to see the same menu
options as the users of Visual Studio professional: from the Tools menu, select Settings,
and select Expert Settings.
Next: Install the Book's Example Programs
The examples are stored in a self-extracting archive file that automatically extracts to
the c:\Irvine folder. Unless you have some objection to using that location, do not alter the
path. (Lab managers: you can designate c:\Irvine directory as read-only.).
Filename Description
Irvine16.inc Include file used with the Irvine16 link library (16-bit applications)
Irvine32.inc Include file used with the Irvine32 link library (32-bit applications)
A subdirectory named Examples will contain all the example programs shown in the book,
as well as all the source code for the book's 16- and 32-bit link libraries.
EXAMPLE: You should write the following program in the editor window:
CODE:
INCLUDE Irvine32.inc
.data
myMessage BYTE "Hello World of Assembly Language",0dh,0ah,0
.code
main PROC
call Clrscr
mov edx,OFFSET myMessage
call WriteString
exit
main ENDP
END main
OUTPUT:
The "Press any key to continue..." message is automatically generated by Visual Studio.
Congratulations, you have just run your first Assembly Language program.
Press any key to close the Console window.
Lab 1- Exercise:
LAB 2
Assembly Language Fundamentals I
1. Sample CODE:
INCLUDE Irvine32.inc
.data
.code
main PROC
mov eax,5 ; move 5 to the EAX register
add eax,6 ; add 6 to the EAX register
call WriteInt ; display value in EAX
exit ; quit
main ENDP
END main
2. Data Representation
If no radix is given, the integer constant is assumed to be decimal. Here are some examples
using different radixes:
Example:
30d, 6Ah, 42, 1101b
• Hexadecimal beginning with letter must have leading 0: 0A5h ƒ
• If no radix is given, the integer constant is assumed to be decimal
3. Segments:
Following are some directives that are widely used in assembly language programs:
1. The .DATA directive identifies the area of a program containing variables:
.data
2. The .CODE directive identifies the area of a program containing executable
instructions:
.code
3. The .STACK directive identifies the area of a program holding the runtime stack,
setting its size: .stack 1000h
4. Data Registers
Four 32-bit data registers are used for arithmetic, logical, and other operations. These 32-
bit registers can be used in three ways −
• As complete 32-bit data registers: EAX, EBX, ECX, EDX.
• Lower halves of the 32-bit registers can be used as four 16-bit data registers: AX,
BX, CX and DX.
• Lower and higher halves of the above-mentioned four 16-bit registers can be used
as eight 8-bit data registers: AH, AL, BH, BL, CH, CL, DH, and DL.
Figure 1.1
Some of these data registers have specific use in arithmetical operations.
AX is the primary accumulator: it is used in input/output and most arithmetic instructions. For
example, in multiplication operation, one operand is stored in EAX or AX or AL register according to the
size of the operand.
CX is known as the count register: as the ECX, CX registers store the loop count in iterative
operations.
DX is known as the data register: It is also used in input/output operations. It is also used with AX
register along with DX for multiply and divides operations involving large values.
CODE:
INCLUDE Irvine32.inc
.code
main PROC
mov eax,10000h ; EAX = 10000h
add eax,40000h ; EAX = 50000h
call DumpRegs ; display registers
exit
main ENDP
END main
Syntax:
MUL reg/mem8
MUL reg/mem16
MUL reg/mem32
The single operand in the MUL instruction is the multiplier. Table 7-2 shows the default
multiplicand and product, depending on the size of the multiplier. Because the destination
operand is twice the size of the multiplicand and multiplier, overflow cannot occur. MUL
sets the Carry and Overflow flags if the upper half of the product is not equal to zero. The
Carry flag is ordinarily used for unsigned arithmetic, so we’ll focus on it here. When AX is
multiplied by a 16-bit operand, for example, the product is stored in the combined DX and
AX registers. That is, the high 16 bits of the product are stored in DX, and the low 16 bits
are stored in AX. The Carry flag is set if DX is not equal to zero, which lets us know that the
product will not fit into the lower half of the implied destination operand.
Example:
The following statements multiply 12345h by 1000h, producing a 64-bit product in the
combined EDX and EAX registers. The Carry flag is clear because the upper half of the
product in EDX equals zero:
CODE:
mov eax,12345h
mov ebx,1000h
mul ebx ; EDX:EAX = 0000000012345000h, CF = 0
IMUL reg16,reg/mem16
IMUL reg16,imm8
IMUL reg16,imm16
Following are the 32-bit operand types showing that the multiplier can be a 32-bit register,
a 32-bit memory operand, or an immediate value (8 or 32 bits):
IMUL reg32,reg/mem32
IMUL reg32,imm8
IMUL reg32,imm32
The two-operand formats truncate the product to the length of the destination. If
significant digits are lost, the Overflow and Carry flags are set. Be sure to check one of these
flags after performing an IMUL operation with two operands.
6.2.3. Three-Operand Formats:
The three-operand formats in 32-bit mode store the product in the first operand. The
second operand can be a 16-bit register or memory operand, which is multiplied by the
third operand, an 8- or 16-bit immediate value:
IMUL reg16,reg/mem16,imm8
IMUL reg16,reg/mem16,imm16
IMUL reg32,reg/mem32,imm8
IMUL reg32,reg/mem32,imm32
If significant digits are lost when IMUL executes, the Overflow and Carry flags are set. Be
sure to check one of these flags after performing an IMUL operation with three operands.
Example: IMUL
The following instructions multiply 48 by 4, producing 192 in AX. Although the product is
correct, AH is not a sign extension of AL, so the Overflow flag is set:
CODE:
mov al,48
mov bl,4
imul bl ; AX = 00C0h, OF = 1
mov al,-4
mov bl,4
imul bl ; AX = FFF0h, OF = 0
mov ax,48
mov bx,4
imul bx ; DX:AX = 000000C0h, OF = 0
mov eax,+4823424
mov ebx,-423
imul ebx ; EDX:EAX = FFFFFFFF86635D80h, OF = 0
The following instructions demonstrate two-operand formats:
CODE:
.data
word1 SWORD 4
dword1 SDWORD 4
.code
mov ax,-16 ; AX = -16
mov bx,2 ; BX = 2
imul bx,ax ; BX = -32
imul bx,2 ; BX = -64
imul bx,word1 ; BX = -256
mov eax,-16 ; EAX = -16
mov ebx,2 ; EBX = 2
imul ebx,eax ; EBX = -32
imul ebx,2 ; EBX = -64
imul ebx,dword1 ; EBX = -256
The two-operand and three-operand IMUL instructions use a destination operand that is
the same size as the multiplier. Therefore, it is possible for signed overflow to occur.
Always check the Overflow flag after executing these types of IMUL instructions. The
following two-operand instructions demonstrate signed overflow because 64,000 cannot
fit within the 16-bit destination operand:
mov ax,-32000
imul ax,2 ; OF = 1
DIV reg/mem8
DIV reg/mem16
DIV reg/mem32
The following table shows the relationship between the dividend, divisor, quotient, and
remainder:
In 64-bit mode, the DIV instruction uses RDX:RAX as the dividend, and it permits the
divisor to be a 64-bit register or memory operand. The quotient is stored in RAX, and the
remainder in RDX.
CODE:
INCLUDE Irvine32.inc
.data
.code
main PROC
mov eax,10
mov ebx,2
sub edx,edx
div ebx
call writeDec
call dumpregs
exit
main ENDP
END main
Lab 2- Exercise:
LAB 3
Assembly Language Fundamentals II
1. Identifiers:
Identifiers – a programmer-choice name
Examples:
✓ var1,
✓ Count,
✓ $first,
✓ _main,
✓ MAX ,
✓ open_file, xVal
3. Directives:
Commands that are recognized and acted upon by the assembler.
✓ Not part of the Intel instruction set
✓ Directives do not execute at run time, whereas instructions do.
✓ Used to declare code, data areas, select memory model, declare procedures, etc.
✓ Not case sensitive: It recognizes .data, .DATA, and .Data as equivalent.
Example Code:
myVar DWORD 26 ; DWORD directive
mov ax, myVar ; MOV instruction
4. Instructions:
✓ An instruction is a statement that becomes executable when a program is
assembled.
✓ Instructions are translated by the assembler into machine language bytes, which are
loaded and executed by the CPU at run time.
✓ We use the Intel IA-32 instruction set
Syntax CODE:
[label] mnemonic operand(s) [;comment]
label ;optional
instruction mnemonic required: such as MOV, ADD, SUB, MUL
operands usually required
An instruction contains:
Labels (optional):
✓ Act as place markers
✓ marks the address (offset) of code and data
✓ Follow identifier rules
Data label:
✓ must be unique
✓ example: count (not followed by colon)
Count DWORD 100
Code Label:
✓ target of jump and loop instructions
✓ example: target: (followed by colon)
target:
MOV ax, bx
…
JMP target
Mnemonics (required):
✓ Instruction Mnemonics
✓ memory aid
✓ examples: MOV, ADD, SUB, MUL, CALL
MOV: Move (assign) one value to another
ADD: Add two values
SUB: Subtract one value from another
MUL: Multiply two values
JMP: Jump to a new location
CALL: Call a procedure
Examples:
Example of assembly language instructions having varying numbers of operands:
No operands Code:
stc ; set Carry flag
Comments (optional):
Single-Line comments:
Multi-Line comments:
2. Listing File
✓ Use it to see how your program is compiled
✓ Contains:
o source code
o addresses
o object code (machine language)
o segment names
o symbols (variables, procedures, and constants)
✓ Example: addSub.lst
3. Map File
✓ Information about each program segment:
o starting address
o ending address
o size
o segment type
✓ Example: addSub.map (16-bit version, not generated in 32-bit version)
1. Defining Strings:
To define a string of characters, enclose them in single or double quotation marks. The
most common type of string ends with a null byte (containing 0).
Example:
greeting1 BYTE "Good afternoon",0
greeting2 BYTE 'Good night',0
Byte values must be separated by commas. Without that exception, greeting1 would have
to be defined as:
Example:
greeting1 BYTE 'G','o','o','d'....etc.
A string can be divided between multiple lines without having to supply a label for each
line:
Example:
greeting1 BYTE "Welcome to the Computer Organization "
BYTE "Lab",0dh,0ah
BYTE "If you have any query, contact "
BYTE "Admission deprt.",0dh,0ah,0
The hexadecimal codes 0Dh and 0Ah are alternately called CR/LF (carriage-return line-
feed) or end-of-line characters. When written to standard output, they move the cursor to
the left column of the line following the current line.
Example:
word1 WORD 65535 ; largest unsigned value
word2 SWORD -32768 ; smallest signed value
word3 WORD ? ; Uninitialized, unsigned
Example: Sample Program for unsign word:
CODE:
INCLUDE Irvine32.inc
.data
value word 75
.code
main PROC
mov eax,0
mov ax,value
call writeint
call crlf
exit
main ENDP
END main
OR
INCLUDE Irvine32.inc
.data
value word 75
.code
main PROC
movzx eax,value
call writeint
call crlf
exit
main ENDP
END main
CODE:
INCLUDE Irvine32.inc
.data
value Sword -75
.code
main PROC
movsx eax,value
call writeint
call crlf
exit
main ENDP
END main
3. Conditions:
Conditional execution in assembly language is accomplished by several looping and
branching instructions. These instructions can change the flow of control in a program.
Conditional execution is observed in two scenarios:
S:No Conditional Instructions
Unconditional jump
This is performed by the JMP instruction. Conditional execution often
1 involves a transfer of control to the address of an instruction that does
not follow the currently executing instruction. Transfer of control may
be forward, to execute a new set of instructions or backward, to re-
execute the same steps.
Conditional jump
This is performed by a set of jump instructions j<condition>
2 depending upon the condition. The conditional instructions transfer
the control by breaking the sequential flow and they do it by changing
the offset value in IP.
NOTE: Let us discuss the CMP instruction before discussing the conditional instructions.
Syntax:
CMP destination, source
CMP compares two numeric data fields. The destination operand could be either in register
or in memory. The source operand could be a constant (immediate) data, register or
memory.
3.2. Unconditional Jump:
As mentioned earlier, this is performed by the JMP instruction. Conditional execution often
involves a transfer of control to the address of an instruction that does not follow the
currently executing instruction. Transfer of control may be forward, to execute a new set of
instructions or backward, to re-execute the same steps.
Syntax:
The JMP instruction provides a label name where the flow of control is transferred
immediately. The syntax of the JMP instruction is:
JMP label
Syntax:
LOOP label
Where, label is the target label that identifies the target instruction as in the jump
instructions. The LOOP instruction assumes that the ECX register contains the loop
count. When the loop instruction is executed, the ECX register is decremented and the
control jumps to the target label, until the ECX register value, i.e., the counter reaches the
value zero.
Syntax:
.WHILE constantExpression
statements
.ENDW
CODE:
INCLUDE Irvine32.inc
.data
myMessage BYTE "Hello",0dh,0ah,0
search DWORD ?
.code
main PROC
call Clrscr
call ReadInt
mov search,eax
mov edx,offset myMessage
sub ecx,ecx
.while ecx <= search
call WriteString
inc ecx
.endw
exit
main ENDP
END main
Output:
2. Nested .While loop in Assembly Language:
Assembly language provides the nested loop in which one loop contains inside multiple
loops as shown:
Syntax:
.WHILE constantExpression
statements
.WHILE constantExpression
statements
.
.ENDW
.ENDW
Example:
Make a program that prints right angle triangle. In the below manner:
CODE:
INCLUDE Irvine32.inc
.data
msg1 BYTE"Enter a Number: ",0
num1 DWORD ?
ans DWORD ?
.code
main PROC
;// Prints msg1 while Reads into num1
mov edx, OFFSET msg1
call writestring
call readInt
mov num1,eax
mov ecx,0
mov ebx,1
.while ecx<num1 ;// This loop defines the length
mov eax,ecx
mov ebx,1
call crlf
inc ecx
.endw
call crlf
call waitmsg
exit
main endp
end main
Output:
Lab 5- Exercise:
LAB 6
DUP Operator and Arrays in Assembly Language
1. DUP Operator:
Use DUP to allocate (create space for) an array or string. The DUP operator allocates
storage for multiple data items, using a constant expression as a counter. It is particularly
useful when allocating space for a string or array, and can be used with initialized or
uninitialized data:
Example:
2. Arrays of Words:
Create an array of words by listing the elements. The following array contains a list of
values:
Example:
myList WORD 1,2,3,4,5
4. Array of Doublewords:
Create an array of doublewords by explicitly initializing each element, or use
the DUP operator. Here is an array containing specific unsigned values:
Example:
myList DWORD 1,2,3,4,5
5. Defining QWORD Data:
The QWORD (define quadword) directive allocates storage for 64-bit (8-byte) values:
Example:
quad1 QWORD 1234567812345678h
Example:
quad1 DQ 1234567812345678h
6. Symbolic Constants:
Associate and identifier (a symbol) with an integer expression or some text:
✓ Symbols do not reserve storage.
✓ Used only by the assembler when scanning a program.
✓ Cannot change at run time.
✓ They are used only by the assembler when scanning a program.
Name = expression
Example:
COUNT = 500
..
mov al, COUNT
Example:
Example:
Syntax:
Example:
.data
Prompt BYTE pressKey
MI WORD matrix
.code
matrix EQU 10 * 10
PI EQU pressKey EQU <"Press any key to continue...",0
6.4. TEXTEQU Directive:
TEXTEQU Directive can be define as:
Syntax:
Example:
.data
continueMsg TEXTEQU <"Do you wish to continue (Y/N)?">
rowSize = 5
.data
prompt1 BYTE continueMsg
count TEXTEQU %(rowSize * 2) ; evaluates the expression
setupAL TEXTEQU <mov al,count>
.code
setupAL ; generates: "mov al,10"
Example: Sample program to take 5 inputs from user and print them:
CODE:
INCLUDE Irvine32.inc
.data
array Byte 50 DUP (0)
message1 byte "Enter the 5 number:"
.code
main PROC
mov edx,offset message1
call writestring
mov ecx,0
.while (ecx < 5)
call readdec
mov array[ecx],al
inc ecx
.endw
call crlf
mov ecx,0
.while (ecx < 5)
mov al,array[ecx]
call writedec
call crlf
inc ecx
.endw
exit
main ENDP
END main
OUTPUT:
Lab 6- Exercise:
LAB 7
Assembly Language Stack Memory & Arrays
1. LENGTHOF Operator:
The LENGTHOF operator counts the number of elements in an array.
Example:
.data
.code
mov eax , lengthof byte1 ; eax = 3
call writeint
mov eax , lengthof array1 ; eax = 32
call writeint
mov eax , lengthof array2 ; eax = 15
call writeint
mov eax , lengthof array3 ; eax = 4
call writeint
mov eax , lengthof array4 ; eax = 9
call writeint
2. SIZEOF Operator:
The SIZEOF operator returns a value that is equivalent to multiplying LENGTHOF by TYPE.
In the following example, Array has TYPE 2 and LENGTHOF 32. Therefore, SIZEOF Array
equals 64:
Example:
.data
Array WORD 32 DUP(0)
.code
mov eax, SIZEOF Array ; EAX = 64
call writeint
3. Neg Instruction:
Neg instruction changes the sign of value.
Example:
.data
value SDWORD 10
.code
main proc
mov eax, value
neg eax
call writeint ; eax = -10
exit
main ENDP
END main
4. Stack Memory:
4.1. PUSH Instruction:
Syntax:
– PUSH register/variable16
– PUSH register/variable32
– PUSH Constant (any number)
Example of Stack:
CODE:
.data
var1 Dword 100
var2 Dword 200
var3 Dword 300
var4 Dword 400
var5 Dword ?
.code
main PROC
push var1
push var2
push var3
push var4
mov eax,500
push eax
pop eax
call writedec
call crlf
pop eax
call writedec
call crlf
pop eax
call writedec
call crlf
pop var5
mov eax,var5
call writedec
call crlf
pop eax
call writedec
call crlf
exit
main ENDP
END main
5. Random32:
The Random32 procedure generates and returns a 32-bit random integer in EAX.
Example:
.data
Value DWORD ?
.code
call Random32
mov Value,eax
6. RandomRange:
The RandomRange procedure produces a random integer within the range of 0 to n-1,
where n is an input parameter passed in the EAX register.
Example:
.data
Value DWORD ?
.code
mov eax,100
call RandomRange
mov Value,eax
7. Randomize:
Randomize generate a Unique sequence of numbers. You need only to call Randomize once
at the beginning of a program.
Example:
TITLE Randoms (main.asm)
INCLUDE Irvine32.inc
.data
.code
main PROC
call Randomize
mov ecx,10
L1:
mov eax,50
call RandomRange
call writeDec
call crlf
loop L1
exit
main ENDP
END main
.data
char BYTE ?
.code
main proc
call ReadChar
mov char,al
call crlf
call writechar
exit
main ENDP
END main
9. ReadHex & WriteHex:
Example:
INCLUDE Irvine32.inc
.data
hex Dword ?
.code
main proc
call Readhex
mov hex,eax
call crlf
call writehex
exit
main ENDP
END main
Lab 7- Exercise:
LAB 8
Assembly Language Procedures
1. Assembly Procedures:
Procedures or subroutines are very important in assembly language, as the assembly
language programs tend to be large. Procedures are identified by a name. Following this
name, the body of the procedure is described which performs a well-defined job. End of the
procedure is indicated by a return statement.
Syntax:
Proc_name:
Procedure body
….
Ret
The procedure is called from another function by using the CALL instruction. The CALL
instruction should have the name of the called procedure as an argument as shown below:
Syntax:
Call Procedure_name
The called procedure returns the control to the calling procedure by using the RET
instruction.
CALL-RET Example (1 of 2)
main PROC
00000020 call MySub
0000025 is the offset of the instruction 00000025 mov eax,ebx
immediately following the CALL .
instruction .
main ENDP
MySub PROC
00000040 is the offset of the first 00000040 mov
instruction inside MySub eax,edx
.
.
ret
MySub ENDP
00000025 ESP 00000040
00000025 ESP 00000025
EIP
EIP
Example:
INCLUDE Irvine32.inc
.data
.code
addition PROC
add eax,ebx
ret
addition ENDP
main PROC
mov eax,4
mov ebx,3
call addition
call writedec
call crlf
exit
main ENDP
END main
2. Nested Procedure Call:
Example:
Remember the nested loop we created. It's easy to push the outer loop counter before
entering the inner loop:
CODE:
mov ecx,100 ; set outer loop count
L1: ; begin the outer loop
push ecx ; save outer loop count
mov ecx,20 ; set inner loop count
L2: ; begin the inner loop
;
loop L2 ; repeat the inner loop
pop ecx ; restore outer loop count
loop L1 ; repeat the outer loop
Lab 8- Exercise:
LAB 9
Assembly Floating Point Unit Stack
Example: The following example loads two direct operands on the FPU
stack:
CODE:
.data
dblOne REAL8 23.4
dblTwo REAL8 10.1
.code
fld dblOne ; ST(0) = 23.4
fld dblTwo ; ST(0) = 10.1 , ST(1) = 23.4
3. Reading and Writing Floating-Point Values
3.1. ReadFloat:
Reads a floating-point value from the keyboard and pushes it on the floating-point stack.
Use “Call Readfloat” procedure for user input.
3.2. WriteFloat:
Writes the floating-point value at ST(0) to the console window in exponential format.
ReadFloat accepts a wide variety of floating-point formats.
Example:
35
+35.
-3.5
.35
3.5E5
3.5E005
-3.5E+5
3.5E-4
+3.5E-4
Use “Call Writefloat” procedure for Display.
4. ShowFPUStack procedure
ShowFPUStack Another useful procedure,displays the FPU stack. Call it with no
parameters:
CODE:
call ShowFPUStack
5. fstp instruction
CODE:
fstp variable_name ; store ST(0) to variable
6. finit instruction
Initialize floating point register stack with 0.
CODE:
Finit
Example:
.data
val Real4 ?
val2 Real4 ?
ans Real4 ?
msg1 byte "Enter 1st value :",0
msg2 byte "Enter 2nd value :",0
msg3 byte "Your Sum is :",0
msg4 byte "Your Sub is :",0
msg5 byte "Your mul is :",0
msg6 byte "Your div is :",0
.code
main PROC
finit
mov edx,offset msg1
call writestring
call readfloat
fstp val
call crlf
mov edx,offset msg2
call writestring
call readfloat
fstp val2
fld val2
fadd val
call crlf
mov edx,offset msg3
call writestring
call writefloat
call crlf
fld val
fsub val2
mov edx,offset msg4
call writestring
call writefloat
finit
fld val
fdiv val2
call crlf
mov edx,offset msg6
call writestring
call writefloat
fld val
fmul val2
call crlf
mov edx,offset msg5
call writestring
call writefloat
call crlf
exit
main ENDP
END main
.code
main PROC
mov edx,OFFSET input_string ; point to the input_string
mov ecx,SIZEOF input_string ; store maximum length characters
call ReadString ; take input from user
mov store_string_length,eax ; number of characters
mov edx,OFFSET input_string
call writestring
call crlf
exit
main ENDP
END main
Lab 9- Exercise:
LAB 10
Conditional LOOP
Syntax:
LOOPE destination
LOOPZ destination
Logic:
• ECX ← ECX – 1
• if ECX > 0 and ZF=1, jump to destination
Syntax:
LOOPNZ destination
LOOPNE destination
Logic:
• ECX ← ECX – 1
• if ECX > 0 and ZF=0, jump to destination
Example LOOPNZ:
The following code finds the first positive value in an array:
CODE:
.data
array SWORD -3,-6,-1,-10,10,30,40,4
sentinel SWORD 0
.code
mov esi,OFFSET array
mov ecx,LENGTHOF array
next:
test WORD PTR [esi],8000h ; test sign bit
pushfd ; push flags on stack
add esi,TYPE array
popfd ; pop flags from stack
loopnz next ; continue loop
jnz quit ; none found
sub esi,TYPE array ; ESI points to value
quit:
NOTE: Locate the first nonzero value in the array. If none is found, let ESI point to the
sentinel value:
CODE:
.data
array SWORD 50 DUP(?)
sentinel SWORD 0FFFFh
.code
mov esi,OFFSET array
mov ecx,LENGTHOF array
L1: cmp WORD PTR [esi],0 ; check for zero
Solution:
.data
array SWORD 50 DUP(?)
sentinel SWORD 0FFFFh
.code mov esi,OFFSET array
mov ecx,LENGTHOF array
L1: cmp WORD PTR [esi],0 ; check for zero
pushfd ; push flags on stack
add esi,TYPE array
popfd ; pop flags from stack
loope next ; continue loop
jz quit ; none found
sub esi,TYPE array ; ESI points to value
quit:
Implement the following pseudo code in assembly language. All values are 32-bit
signed integers:
if( var1 <= var2 )
var3 = 10;
else
{
var3 = 6;
var4 = 7;
}
Expression:
if (al > bl) AND (bl > cl)
X = 1;
5. Compound Expression with AND [2/3]:
Expression:
if (al > bl) AND (bl > cl)
X = 1;
But the following implementation uses 29% less code by reversing the
first relational operator.
cmp al,bl ; first expression...
jbe next ; quit if false
cmp bl,cl ; second expression...
jbe next ; quit if false
mov X,1 ; both are true
next:
Expression:
if (al > bl) OR (bl > cl)
X = 1;
9. WHILE Loop:
A WHILE loop is really an IF statement followed by the body of the loop, followed by an
unconditional jump to the top of the loop. Consider the following example:
The other type of shift is called an arithmetic shift. The newly created bit position is filled
with a copy of the original number’s sign bit. It works only with shift arithmetic right.
A drawback of the shift instructions is that the bits that are shifted out are lost, except that
the last bit shifted out is stored in the carry flag. There may be situations where we want to
keep these bits. The rotate instructions can be used instead. They are divided into two
types: the normal rotate, and the rotate through the carry flag. An example of a rotate
instruction is ROL (rotate left). This instruction shifts each bit to the left according to a
specific count. The highest bit rotates left to become the lowest bit. The last highest bit that
was rotated left is stored in the carry flag.
1. Stack Parameters:
There are two basic ways of passing parameters to procedures. We can pass parameters in
registers or we can pass them on the stack. So far, we have demonstrated the use of register
parameters in the previous lab. The Irvine library also uses register parameters for its
procedures. Register parameters are optimized for program execution speed.
Stack parameters are pushed on the stack before making the procedure call. The called
procedure will have to locate its parameters on the stack.
Consider the SumOf procedure defined in the previous lab. We now redefine it and call it
differently, passing parameters on the stack, rather than in registers as shown below:
CODE Example:
When the SumOf procedure is called, the esp register is pointing at the return address on
top of the stack. The parameters can be located on the stack at addresses [esp+4], [esp+8],
and [esp+12]. Recall that the stack grows downwards towards lower addresses.
1. Cleaning up the Stack Parameters with the RET
Instruction:
When parameters are pushed on the stack, it is important to clean up the stack upon
returning from a procedure. The ret instruction can specify an extra integer constant to
clean up the parameters on the stack. In the above SumOf procedure, 12 bytes are pushed
on the stack for three parameters. The ret 12 instruction is used to increment the esp
register by 12 bytes, in addition to the 4 bytes for popping the return address.
The ArraySum procedure also uses the eax register to accumulate the sum and to hold the
result of the procedure. Since the result is returned in the eax register, its value should not
be preserved by the procedure.
When you specify the parameters of a procedure, the assembler will automatically generate
the first two instructions: push epb and mov ebp, esp. So, there is no need to write them.
The assembler will also insert a leave instruction just before the ret instruction. The leave
instruction is equivalent to two instructions: move esp, ebp and pop ebp. So, there is no
need to write them either. The assembler will also replace the ret instruction with ret n,
where n is equal to the size of the parameters in bytes, so there is no need to specify n. You
can also refer to a parameter by name, rather than by its address inside the procedure (e.g.,
you can replace [ebp+8] by sumaddr). The assembler will replace the parameter name by
its address.
9. INVOKE Directive:
The INVOKE directive simplifies a procedure call by allowing you to pass parameters to a
procedure in a single statement. You can invoke SumDigits as follows:
Example: SumDigits2:
The SumDigits2.asm program is a modified version of SumDigits.asm that uses assembler
directives to simplify the writing of a procedure. Assemble and link SumDigits2.asm. Open
the SumDigits2.lst file and examine the instructions marked with * inserted by the
assembler at the beginning and end of the SumDigits procedure.
CODE:
Lab 12- Exercise:
LAB 13
Recursion in Assembly Language
1. Recursive Procedure:
A recursive procedure is one that calls itself. There are two kind of recursion: direct and
indirect. In direct recursion, the procedure calls itself and in indirect recursion, the first
procedure calls a second procedure, which in turn calls the first procedure.
Recursion could be observed in numerous mathematical algorithms. For example, consider
the case of calculating the factorial of a number. Factorial of a number is given by the
equation:
Equation:
Factorial (n) = n * Factorial ( n – 1 ) for n > 0
Example:
Factorial of 5 is 1 x 2 x 3 x 4 x 5 = 5 x factorial of 4 and this can be a good example of
showing a recursive procedure. Every recursive algorithm must have an ending condition,
i.e., the recursive calling of the program should be stopped when a condition is fulfilled. In
the case of factorial algorithm, the end condition is reached when n is 0.
Example: