0% found this document useful (0 votes)
81 views33 pages

COAL Lectures Week 13 Pat A

This document summarizes key concepts from Chapter 8 of the textbook "Computer Organization and Assembly Language". It discusses recursion, which is when a subroutine calls itself directly or indirectly. Recursion is useful for data structures with repeating patterns like linked lists. The document provides an example of endless recursion that causes a stack overflow. It also discusses how useful recursive subroutines contain a terminating condition. An example is provided to calculate a factorial recursively in assembly code. Other concepts discussed include the .MODEL directive, language specifiers, INVOKE and PROTO directives, and the PROC directive for defining procedures.
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)
81 views33 pages

COAL Lectures Week 13 Pat A

This document summarizes key concepts from Chapter 8 of the textbook "Computer Organization and Assembly Language". It discusses recursion, which is when a subroutine calls itself directly or indirectly. Recursion is useful for data structures with repeating patterns like linked lists. The document provides an example of endless recursion that causes a stack overflow. It also discusses how useful recursive subroutines contain a terminating condition. An example is provided to calculate a factorial recursively in assembly code. Other concepts discussed include the .MODEL directive, language specifiers, INVOKE and PROTO directives, and the PROC directive for defining procedures.
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/ 33

Computer Organization and

Assembly Language
Week 13 part a
Chapter 8 “Advanced Procedures”
Recursion
• A recursive subroutine is one that calls itself, either directly or
indirectly.

• Recursion , the practice of calling recursive subroutines, can be a


powerful tool when working with data structures that have repeating
patterns. Examples are linked lists and various types of connected
graphs where a program must retrace its path.
Recursion
Endless Recursion:(Example)
; Endless Recursion (Endless.asm)
INCLUDE Irvine32.inc
.data
endlessStr BYTE "This recursion never stops",0
.code
In this program each time the
main PROC
procedure calls itself, it uses up 4
call Endless
bytes of stack space when the CALL
exit instruction pushes the return
main ENDP address. The RET instruction is
Endless PROC never executed, and the program
mov edx, OFFSET endlessStr halts when the stack overflows.
call WriteString
call Endless
ret ; never executes
Endless ENDP
END main
Useful recursive subroutines
• Useful recursive subroutines always contain a terminating condition
(base case). When the terminating condition becomes true, the stack
unwinds when the program executes all pending RET instructions.
Example: Calculating Factorial
• This function calculates the factorial of integer n. A new value of n is
saved in each stack frame:

int function factorial(int n)


{
if(n == 0)
return 1;
else
return n * factorial(n−1);
}

factorial(5);
Calculating Factorial (Assembly code)
; Calculating a Factorial (Fact.asm)
INCLUDE Irvine32.inc
.code
main PROC
push 5 ; calc 5!
call Factorial ; calculate factorial (EAX)
call WriteDec ; display it
call Crlf
exit
main ENDP
;----------------------------------------------------
Calculating Factorial(Assembly code continued)
.MODEL Directive

[[, langtype]] [[, stackoption]]


.MODEL Directive
.MODEL memorymodel [[, langtype]] [[, stackoption]]

Initializes the program memory model.


• The memorymodel can be TINY, SMALL, COMPACT, MEDIUM, LARGE,
HUGE, or FLAT.

• The langtype can be C, BASIC, FORTRAN, PASCAL, SYSCALL, or


STDCALL.

• The stackoption can be NEARSTACK or FARSTACK.


Memory Models
Language Specifier
INVOKE Directive
Example:
• Using the CALL instruction, for example, we could call a procedure named
DumpArray after executing several PUSH instructions:

push TYPE array


push LENGTHOF array
push OFFSET array
call DumpArray
• The equivalent statement using INVOKE is reduced to a single line in which
the arguments are listed in reverse order (assuming STDCALL is in effect):

INVOKE DumpArray, OFFSET array, LENGTHOF array, TYPE array


Example(cont)
• INVOKE permits almost any number of arguments, and individual
arguments can appear on separate source code lines. The following
INVOKE statement includes helpful comments:

INVOKE DumpArray, ; displays an array


OFFSET array, ; points to the array
LENGTHOF array, ; the array length
TYPE array ; array component size
Important points to remember
If you pass arguments smaller than 32 bits to a procedure, INVOKE
frequently causes the assembler to overwrite EAX and EDX when it
widens the arguments before pushing them on the stack.
You can avoid this behavior by always passing 32-bit arguments to
INVOKE, or you can save and restore EAX and EDX before and after the
procedure call.
ADDR Operator (Used with INVOKE to pass a pointer argument)
ADDR Example

Code generated by Assembler assuming STDCALL is in effect


PROC Directive
PROC Example (1)
• The AddTwo procedure receives two integers and returns their sum in
EAX.
• C++ programs typically return 32-bit integers from functions in EAX.
PROC Example(2) MASM-generated code
Read_File PROC
Read_File PROC USES eax ebx,
push ebp
pBuffer:PTR BYTE mov ebp, esp
LOCAL fileHandle:DWORD add esp, 0FFFFFFFCh ; equal to sub esp, 4
mov esi, pBuffer push eax ; save EAX
push ebx ; save EBX
mov fileHandle, eax
mov esi, dword ptr [ebp+8] ; pBuffer
. mov dword ptr [ebp−4], eax ; fileHandle
. .
ret .
pop ebx
Read_File ENDP
pop eax
leave
ret 4
Read_File ENDP
PROTO Directive
• Creates a procedure prototype

• Syntax:
– label PROTO paramList

• Every procedure called by the INVOKE directive must have a


prototype

• A complete procedure definition can also serve as its own prototype


PROTO Directive
• Standard configuration: PROTO appears at top of the program listing,
INVOKE appears in the code segment, and the procedure
implementation occurs later in the program:
Steps for creating Prototype
• Prototype for a procedure can be created by copying the
PROC statement and making the following changes:

• Change the word PROC to PROTO.


• Remove the USES operator if any, along with its register list.
PROTO Example 1:
• Prototype for the ArraySum procedure, showing its parameter list:
PROTO and INVOKE Example 2:
• The following example is used to explain valid calls and errors
detected by MASM and not detected by MASM when using INVOKE
and PROTO.
• Suppose prototype for Sub1 is declared as:
Sub1 PROTO, p1:BYTE, p2:WORD, p3:PTR BYTE
• Also assume following variables are defined in data segment:
.data
byte_1 BYTE 10h
word_1 WORD 2000h
word_2 WORD 3000h
dword_1 DWORD 12345678h
• An example of valid call to Sub1:
• INVOKE Sub1, byte_1, word_1, ADDR byte_1
• Equivalent code generated by MASM for this INVOKE:
push 404000h ; ptr to byte_1
sub esp,2 ; pad stack with 2 bytes
push word ptr ds:[00404001h] ; value of word_1 EAX is overwritten and the sub esp, 2
mov al,byte ptr ds:[00404000h] ; value of byte_1 instruction pads the subsequent stack entry
to 32 bits
push eax
call 00401071
Errors detected by MASM:
• If an argument exceeds the size of a declared parameter, MASM
generates an error:
INVOKE Sub1, word_1, word_2, ADDR byte_1 ; arg 1 error
• MASM generates errors if Sub1 is invoked using too few or too many
arguments:
INVOKE Sub1, byte_1, word_2 ; error: too few arguments

INVOKE Sub1, byte_1, ; error: too many arguments


word_2, ADDR byte_1, word_2
Errors not detected by MASM:
• If an argument’s type is smaller than a declared parameter, MASM
does not detect an error:
INVOKE Sub1, byte_1, byte_1, ADDR byte_1
Instead, MASM expands the smaller argument to the size of the
declared parameter. In the following code generated by our INVOKE
example, the second argument (byte_1) is expanded into EAX before
pushing it on the stack.

• If a doubleword is passed when a pointer was expected, no error is


detected. This type of error usually leads to a runtime error when the
subroutine tries to use the stack parameter as a pointer.
Homework Question:
Exercise:
Write a procedure named CountMatches that receives points to two
arrays of signed doublewords, and a third parameter that indicates the
length of the two arrays. For each element in the first array, if the
corresponding in the second array is equal, increment a count. At the
end, return a count of the number of matching array elements in EAX.
Write a test program that calls your procedure and passes pointers to
two different pairs of arrays. Use the INVOKE statement to call your
procedure and pass stack parameters. Create a PROTO declaration for
CountMatches. Save and restore any registers (other than EAX)
changed by your procedure.
Adapted from:
1. Intel x86 Instruction Set Architecture, Computer Organization and
Assembly Languages Yung-Yu Chuang
2. Assembly Language for x86 Processors by Kip R. Irvine (7th Edition)
3. Assembly Language Programming and organization of the IBM PC
by Ytha Yu Charles Marut

You might also like