Download presentation
Presentation is loading. Please wait.
Published byGavin Garrett Modified over 8 years ago
1
Procedure Computer Organization and Assembly Languages Yung-Yu Chuang 2007/12/24 with slides by Kip Irvine
2
2 Overview Stack Operations Defining and Using Procedures Stack frames, parameters and local variables Recursion Related directives
3
Stack operations
4
4 Stacks LIFO (Last-In, First-Out) data structure. push/pop operations You probably have had experiences on implementing it in high-level languages. Here, we concentrate on runtime stack, directly supported by hardware in the CPU. It is essential for calling and returning from procedures.
5
5 Runtime stack Managed by the CPU, using two registers –SS (stack segment) –ESP (stack pointer) * : point to the top of the stack usually modified by CALL, RET, PUSH and POP * SP in Real-address mode memory stack segment SS ESP
6
6 PUSH and POP instructions PUSH syntax: –PUSH r/m16 –PUSH r/m32 –PUSH imm32 POP syntax: –POP r/m16 –POP r/m32
7
7 PUSH operation (1 of 2) A push operation decrements the stack pointer by 2 or 4 (depending on operands) and copies a value into the location pointed to by the stack pointer. 00000006 ESP 1000 0FFC 0FF8 0FF4 0FF0 0FEC 00000006 ESP 1000 0FFC 0FF8 0FF4 0FF0 0FEC 000000A5 PUSH 0A5h
8
8 PUSH operation (2 of 2) The same stack after pushing two more integers: 00000006 ESP 1000 0FFC 0FF8 0FF4 0FF0 0FEC 000000A5 00000001 00000006 ESP 1000 0FFC 0FF8 0FF4 0FF0 0FEC 000000A5 00000001 00000002 PUSH 01hPUSH 02h
9
9 POP operation Copies value at stack[ESP] into a register or variable. Adds n to ESP, where n is either 2 or 4, depending on the attribute of the operand receiving the data 00000006 ESP 1000 0FFC 0FF8 0FF4 0FF0 0FEC 000000A5 00000001 00000002 00000006 ESP 1000 0FFC 0FF8 0FF4 0FF0 0FEC 000000A5 00000001 POP EAX EAX=00000002
10
10 When to use stacks Temporary save area for registers To save return address for CALL To pass arguments Local variables Applications which have LIFO nature, such as reversing a string
11
11 Example of using stacks push esi; push registers push ecx push ebx mov esi,OFFSET dwordVal ; starting OFFSET mov ecx,LENGTHOF dwordVal; number of units mov ebx,TYPE dwordVal ;size of a doubleword call DumpMem ; display memory pop ebx; opposite order pop ecx pop esi Save and restore registers when they contain important values. Note that the PUSH and POP instructions are in the opposite order:
12
12 Example: Nested Loop 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 When creating a nested loop, push the outer loop counter before entering the inner loop:
13
13 Example: reversing a string.data aName BYTE "Abraham Lincoln",0 nameSize = ($ - aName) – 1.code main PROC ; Push the name on the stack. mov ecx,nameSize mov esi,0 L1: movzx eax,aName[esi]; get character push eax; push on stack inc esi Loop L1
14
14 Example: reversing a string ; Pop the name from the stack, in reverse, ; and store in the aName array. mov ecx,nameSize mov esi,0 L2: pop eax; get character mov aName[esi],al; store in string inc esi Loop L2 exit main ENDP END main
15
15 Related instructions PUSHFD and POPFD –push and pop the EFLAGS register –LAHF, SAHF are other ways to save flags PUSHAD pushes the 32-bit general-purpose registers on the stack in the following order –EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI POPAD pops the same registers off the stack in reverse order –PUSHA and POPA do the same for 16-bit registers
16
16 Example MySub PROC pushad... ; modify some register... popad ret MySub ENDP Do not use this if your procedure uses registers for return values
17
Defining and using procedures
18
18 Creating Procedures Large problems can be divided into smaller tasks to make them more manageable A procedure is the ASM equivalent of a Java or C++ function Following is an assembly language procedure named sample: sample PROC. ret sample ENDP A named block of statements that ends with a return.
19
19 Documenting procedures A description of all tasks accomplished by the procedure. Receives: A list of input parameters; state their usage and requirements. Returns: A description of values returned by the procedure. Requires: Optional list of requirements called preconditions that must be satisfied before the procedure is called. Suggested documentation for each procedure: For example, a procedure of drawing lines could assume that display adapter is already in graphics mode.
20
20 Example: SumOf procedure ;----------------------------------------------- SumOf PROC ; ; Calculates and returns the sum of three 32-bit ; integers. ; Receives: EAX, EBX, ECX, the three integers. ; May be signed or unsigned. ; Returns: EAX = sum, and the status flags ; (Carry, Overflow, etc.) are changed. ; Requires: nothing ;----------------------------------------------- add eax,ebx add eax,ecx ret SumOf ENDP
21
21 CALL and RET instructions The CALL instruction calls a procedure –pushes offset of next instruction on the stack –copies the address of the called procedure into EIP The RET instruction returns from a procedure –pops top of stack into EIP We used jl and jr in our toy computer for CALL and RET, BL and MOV PC, LR in ARM.
22
22 CALL-RET example (1 of 2) main PROC 00000020 call MySub 00000025 mov eax,ebx. main ENDP MySub PROC 00000040 mov eax,edx. ret MySub ENDP 0000025 is the offset of the instruction immediately following the CALL instruction 00000040 is the offset of the first instruction inside MySub
23
23 CALL-RET example (2 of 2) The CALL instruction pushes 00000025 onto the stack, and loads 00000040 into EIP The RET instruction pops 00000025 from the stack into EIP ESP 00000025 00000040 EIP ESP 00000025 EIP
24
24 Nested procedure calls 0100 0200 0300 EIP Stack 0050 0150 0250
25
25 Local and global labels main PROC jmp L2; error! L1::; global label exit main ENDP sub2 PROC L2:; local label jmp L1; ok ret sub2 ENDP A local label is visible only to statements inside the same procedure. A global label is visible everywhere.
26
26 Procedure parameters (1 of 3) A good procedure might be usable in many different programs Parameters help to make procedures flexible because parameter values can change at runtime General registers can be used to pass parameters
27
27 Procedure parameters (2 of 3) ArraySum PROC mov esi,0; array index mov eax,0; set the sum to zero L1: add eax,myArray[esi]; add each integer to sum add esi,4; point to next integer loop L1; repeat for array size mov theSum,eax; store the sum ret ArraySum ENDP The ArraySum procedure calculates the sum of an array. It makes two references to specific variable names:
28
28 Procedure parameters (3 of 3) ArraySum PROC ; Recevies: ESI points to an array of doublewords, ; ECX = number of array elements. ; Returns: EAX = sum ;------------------------------------------------ push esi push ecx mov eax,0; set the sum to zero L1: add eax,[esi]; add each integer to sum add esi,4; point to next integer loop L1; repeat for array size pop ecx pop esi ret ArraySum ENDP This version returns the sum of any doubleword array whose address is in ESI. The sum is returned in EAX:
29
29 Calling ArraySum.data array DWORD 10000h, 20000h, 30000h, 40000h theSum DWORD ?.code main PROC mov esi, OFFSET array mov ecx, LENGTHOF array callArraySum movtheSum, eax
30
30 USES operator Lists the registers that will be saved (to avoid side effects) (return register shouldn ’ t be saved) ArraySum PROC USES esi ecx mov eax,0 ; set the sum to zero... MASM generates the following code: ArraySum PROC push esi push ecx. pop ecx pop esi ret ArraySum ENDP
31
Stack frames, parameters and local variables
32
32 Stack frame Also known as an activation record Area of the stack set aside for a procedure's return address, passed parameters, saved registers, and local variables Created by the following steps: –Calling procedure pushes arguments on the stack and calls the procedure. –The subroutine is called, causing the return address to be pushed on the stack. –The called procedure pushes EBP on the stack, and sets EBP to ESP. –If local variables are needed, a constant is subtracted from ESP to make room on the stack. –The registers needed to be saved are pushed.
33
33 Stack frame ret addrebp EBP ESP local variables [EBP+4] [EBP+8] [EBP-4] parameters saved registers ebp ESP EBP
34
34 Explicit access to stack parameters A procedure can explicitly access stack parameters using constant offsets from EBP. –Example: [ebp + 8] EBP is often called the base pointer or frame pointer because it holds the base address of the stack frame. EBP does not change value during the procedure. EBP must be restored to its original value when a procedure returns.
35
35 Parameters Two types: register parameters and stack parameters. Stack parameters are more convenient than register parameters. pushad mov esi,OFFSET array mov ecx,LENGTHOF array mov ebx,TYPE array call DumpMem popad push TYPE array push LENGTHOF array push OFFSET array call DumpMem register parameters stack parameters
36
36 Parameters push b push a call AddTwo push OFFSET b push OFFSET a call AddTwo call by valuecall by reference int sum=AddTwo(a, b);int sum=AddTwo(&a, &b);.date a DWORD 5 b DWORD 6 56offset(a)offset(b) ESP
37
37 Stack frame example.data sum DWORD ?.code push 6 ; second argument push 5 ; first argument call AddTwo; EAX = sum mov sum,eax; save the sum AddTwo PROC push ebp mov ebp,esp. 65ret addrebp ESP EBP [EBP+4] [EBP+8] [EBP+12]
38
38 Stack frame example AddTwo PROC push ebp mov ebp,esp ; base of stack frame mov eax,[ebp + 12] ; second argument (6) add eax,[ebp + 8] ; first argument (5) pop ebp ret 8 ; clean up the stack AddTwo ENDP ; EAX contains the sum 65ret addrebp EBP [EBP+4] [EBP+8] [EBP+12] Who should be responsible to remove arguments? It depends on the language model.
39
39 RET Instruction Return from subroutine Pops stack into the instruction pointer (EIP or IP). Control transfers to the target address. Syntax: –RET –RET n Optional operand n causes n bytes to be added to the stack pointer after EIP (or IP) is assigned a value.
40
40 Passing arguments by reference The ArrayFill procedure fills an array with 16-bit random integers The calling program passes the address of the array, along with a count of the number of array elements:.data count = 100 array WORD count DUP(?).code push OFFSET array push COUNT call ArrayFill
41
41 Passing arguments by reference ArrayFill PROC push ebp mov ebp,esp pushad mov esi,[ebp+12] mov ecx,[ebp+8]. ArrayFill can reference an array without knowing the array's name: offset(array)countret addrebp EBP [EBP+4] [EBP+8] [EBP+12]
42
42 Passing 8-bit and 16-bit arguments When passing stack argements, it is best to push 32-bit operands to keep ESP aligned on a doubleword boundary. Uppercase PROC push ebp mov ebp, esp mov al, [ebp+8] cmp al, ‘a’ jb L1 cmp al, ‘z’ ja L1 sub al, 32 L1: pop ebp ret 4 Uppercase ENDP push ‘x’ ; error Call Uppercase.data charVal BYTE ‘x’.code movzx eax, charVal push eax Call Uppercase
43
43 ecx Saving and restoring registers When using stack parameters, avoid USES. MySub2 PROC USES ecx, edx push ebp mov ebp, esp mov eax, [ebp+8] pop ebp ret 4 MySub2 ENDP MySub2 PROC push ecx push edx push ebp mov ebp, esp mov eax, [ebp+8] pop ebp pop edx pop ecx ret 4 MySub2 ENDP parameterret addredx ESP,EBP [EBP+8] [EBP+16] ebp
44
44 Local variables The variables defined in the data segment can be taken as static global variables. A local variable is created, used, and destroyed within a single procedure (block) Advantages of local variables: –Restricted access: easy to debug, less error prone –Efficient memory usage –Same names can be used in two different procedures –Essential for recursion lifetime=program duration visibility=the whole program
45
45 Creating local variables Local variables are created on the runtime stack, usually above EBP. To explicitly create local variables, subtract their total size from ESP. MySub PROC push ebp mov ebp,esp sub esp,8 mov [ebp-4],123456h mov [ebp-8],0.. ret addrebp … EBP ESP [EBP+4] [EBP+8] [EBP-4] [EBP-8]
46
46 Local variables They can’t be initialized at assembly time but can be assigned to default values at runtime. void MySub() { int X=10; int Y=20;... } MySub PROC push ebp mov ebp, esp sub esp, 8 mov DWORD PTR [ebp-4], 10 mov DWORD PTR [ebp-8], 20... mov esp, ebp pop ebp ret MySub ENDP ESP EBP return address stack EBP 10 20
47
47 MySub PROC push ebp mov ebp, esp sub esp, 8 mov DWORD PTR [ebp-4], 10 mov DWORD PTR [ebp-8], 20... mov esp, ebp pop ebp ret MySub ENDP Local variables X_local EQU DWORD PTR [ebp-4] Y_local EQU DWORD PTR [ebp-8] mov X_local, 10 mov Y_local, 20
48
48 LEA instruction (load effective address) The LEA instruction returns offsets of both direct and indirect operands at run time. –OFFSET only returns constant offsets (assemble time). LEA is required when obtaining the offset of a stack parameter or local variable. For example: CopyString PROC, count:DWORD LOCAL temp[20]:BYTE mov edi,OFFSET count; invalid operand mov esi,OFFSET temp; invalid operand lea edi,count; ok lea esi,temp; ok
49
49 LEA example void makeArray() { char myString[30]; for (int i=0; i<30; i++) myString[i]=‘*’; } makeArray PROC push ebp mov ebp, esp sub esp, 32 lea esi, [ebp-30] mov ecx, 30 L1: mov BYTE PTR [esi], ‘*’ inc esi loop L1 add esp 32 pop ebp ret makeArray ENDP
50
50 ENTER and LEAVE ENTER instruction creates stack frame for a called procedure –pushes EBP on the stack push ebp –set EBP to the base of stack frame mov ebp, esp –reserves space for local variables sub esp, n ENTER nbytes, nestinglevel –nbytes (for local variables) is rounded up to a multiple of 4 to keep ESP on a doubleword boundary –nestinglevel : 0 for now MySub PROC enter 8,0 MySub PROC push ebp mov ebp,esp sub esp,8
51
51 ENTER and LEAVE LEAVE reverses the action of a previous ENTER instruction. MySub PROC push ebp mov ebp, esp sub esp, 8. mov esp, ebp pop ebp ret MySub ENDP MySub PROC enter 8, 0. leave ret MySub ENDP
52
52 LOCAL directive The LOCAL directive declares a list of local variables –immediately follows the PROC directive –each variable is assigned a type Syntax: LOCAL varlist Example: MySub PROC LOCAL var1:BYTE, var2:WORD, var3:SDWORD
53
53 MASM-generated code BubbleSort PROC LOCAL temp:DWORD, SwapFlag:BYTE... ret BubbleSort ENDP BubbleSort PROC push ebp mov ebp,esp add esp,0FFFFFFF8h; add -8 to ESP... mov esp,ebp pop ebp ret BubbleSort ENDP MASM generates the following code:
54
54 Non-Doubleword Local Variables Local variables can be different sizes How are they created in the stack by LOCAL directive: –8-bit: assigned to next available byte –16-bit: assigned to next even (word) boundary –32-bit: assigned to next doubleword boundary
55
55 MASM-generated code ebp ESP EBP [EBP-4] [EBP-8] mov eax, temp mov bl, SwapFlag mov eax, [ebp-4] mov bl, [ebp-5] SwapFlag temp
56
56 Reserving stack space.STACK 4096 Sub1 calls Sub2, Sub2 calls Sub3, how many bytes will you need in the stack? Sub1 PROC LOCAL array1[50]:DWORD; 200 bytes Sub2 PROC LOCAL array2[80]:WORD; 160 bytes Sub3 PROC LOCAL array3[300]:WORD; 300 bytes 660+8(ret addr)+saved registers…
57
Recursion
58
58 Recursion The process created when... –A procedure calls itself –Procedure A calls procedure B, which in turn calls procedure A Using a graph in which each node is a procedure and each edge is a procedure call, recursion forms a cycle:
59
59 Calculating a factorial This function calculates the factorial of integer n. A new value of n is saved in each stack frame: int factorial(int n) { if (n == 0) return 1; else return n*factorial(n-1); } factorial(5);
60
60 Calculating a factorial Factorial PROC push ebp mov ebp,esp mov eax,[ebp+8]; get n cmp eax,0; n > 0? ja L1; yes: continue mov eax,1; no: return 1 jmp L2 L1:dec eax push eax; Factorial(n-1) call Factorial ReturnFact: mov ebx,[ebp+8] ; get n mul ebx ; edx:eax=eax*ebx L2:pop ebp; return EAX ret 4; clean up stack Factorial ENDP
61
61 Calculating a factorial Factorial PROC push ebp mov ebp,esp mov eax,[ebp+8] cmp eax,0 ja L1 mov eax,1 jmp L2 L1:dec eax push eax call Factorial ReturnFact: mov ebx,[ebp+8] mul ebx L2:pop ebp ret 4 Factorial ENDP 12ret mainebp11ret Factorialebp0ret Factorialebp … push 12 call Factorial
62
Related directives
63
63.MODEL directive.MODEL directive specifies a program's memory model and model options (language-specifier). Syntax:.MODEL memorymodel [,modeloptions] memorymodel can be one of the following: –tiny, small, medium, compact, large, huge, or flat modeloptions includes the language specifier: –procedure naming scheme –parameter passing conventions.MODEL flat, STDCALL
64
64 Memory models A program's memory model determines the number and sizes of code and data segments. Real-address mode supports tiny, small, medium, compact, large, and huge models. Protected mode supports only the flat model. Small model: code < 64 KB, data (including stack) < 64 KB. All offsets are 16 bits. Flat model: single segment for code and data, up to 4 GB. All offsets are 32 bits.
65
65 Language specifiers STDCALL (used when calling Windows functions) –procedure arguments pushed on stack in reverse order (right to left) –called procedure cleans up the stack –_name@nn (for example, _AddTwo@8 ) C –procedure arguments pushed on stack in reverse order (right to left) –calling program cleans up the stack (variable number of parameters such as printf ) –_name (for example, _AddTwo ) PASCAL –arguments pushed in forward order (left to right) –called procedure cleans up the stack BASIC, FORTRAN, SYSCALL
66
66 INVOKE directive The INVOKE directive is a powerful replacement for Intel ’ s CALL instruction that lets you pass multiple arguments Syntax: INVOKE procedureName [, argumentList] ArgumentList is an optional comma-delimited list of procedure arguments Arguments can be: –immediate values and integer expressions –variable names –address and ADDR expressions –register names
67
67 INVOKE examples.data byteVal BYTE 10 wordVal WORD 1000h.code ; direct operands: INVOKE Sub1,byteVal,wordVal ; address of variable: INVOKE Sub2,ADDR byteVal ; register name, integer expression: INVOKE Sub3,eax,(10 * 20) ; address expression (indirect operand): INVOKE Sub4,[ebx]
68
68 INVOKE example.data val1 DWORD 12345h val2 DWORD 23456h.code INVOKE AddTwo, val1, val2 push val1 push val2 call AddTwo
69
69 ADDR operator.data myWord WORD ?.code INVOKE mySub,ADDR myWord Returns a near or far pointer to a variable, depending on which memory model your program uses: Small model: returns 16-bit offset Large model: returns 32-bit segment/offset Flat model: returns 32-bit offset Simple example:
70
70 ADDR example.data Array DWORD 20 DUP(?).code... INVOKE Swap, ADDR Array, ADDR [Array+4] push OFFSET Array+4 push OFFSET Array Call Swap
71
71 PROC directive The PROC directive declares a procedure with an optional list of named parameters. Syntax: label PROC [attributes] [USES] paramList paramList is a list of parameters separated by commas. Each parameter has the following syntax: paramName:type type must either be one of the standard ASM types (BYTE, SBYTE, WORD, etc.), or it can be a pointer to one of these types. Example: foo PROC C USES eax, param1:DWORD
72
72 PROC example AddTwo PROC, val1:DWORD, val2:DWORD mov eax,val1 add eax,val2 ret AddTwo ENDP The AddTwo procedure receives two integers and returns their sum in EAX. C++ programs typically return 32-bit integers from functions in EAX. AddTwo PROC, push ebp mov ebp, esp mov eax, dword ptr [ebp+8] add eax, dword ptr [ebp+0Ch] leave ret 8 AddTwo ENDP
73
73 PROC example Read_File PROC USES eax, ebx, pBuffer:PTR BYTE LOCAL fileHandle:DWORD mov esi, pBuffer mov fileHandle, eax. ret Read_File ENDP Read_File PROC push ebp mov ebp, esp add esp, 0FFFFFFFCh push eax push ebx mov esi, dword ptr [ebp+8] mov dword ptr [ebp-4], eax. pop ebx pop eax ret Read_File ENDP
74
74 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
75
75 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: MySub PROTO ; procedure prototype.code INVOKE MySub ; procedure call MySub PROC ; procedure implementation. MySub ENDP
76
76 PROTO example Prototype for the ArraySum procedure, showing its parameter list: ArraySum PROTO, ptrArray:PTR DWORD, ; points to the array szArray:DWORD ; array size ArraySum PROC USES esi, ecx, ptrArray:PTR DWORD, ; points to the array szArray:DWORD ; array size
77
Multimodule programs
78
78 Multimodule programs A multimodule program is a program whose source code has been divided up into separate ASM files. Each ASM file (module) is assembled into a separate OBJ file. All OBJ files belonging to the same program are linked using the link utility into a single EXE file. –This process is called static linking
79
79 Advantages Large programs are easier to write, maintain, and debug when divided into separate source code modules. When changing a line of code, only its enclosing module needs to be assembled again. Linking assembled modules requires little time. A module can be a container for logically related code and data encapsulation: procedures and variables are automatically hidden in a module unless you declare them public
80
80 Creating a multimodule program Here are some basic steps to follow when creating a multimodule program: –Create the main module –Create a separate source code module for each procedure or set of related procedures –Create an include file that contains procedure prototypes for external procedures (ones that are called between modules) –Use the INCLUDE directive to make your procedure prototypes available to each module
81
81 Multimodule programs MySub PROC PRIVATE sub1 PROC PUBLIC EXTERN sub1@0:PROC PUBLIC count, SYM1 SYM1=10.data count DWORD 0 EXTERN name:type
82
82 INCLUDE file INCLUDE Irvine32.inc PromptForIntegers PROTO, ptrPrompt:PTR BYTE,; prompt string ptrArray:PTR DWORD,; points to the array arraySize:DWORD; size of the array ArraySum PROTO, ptrArray:PTR DWORD,; points to the array count:DWORD; size of the array DisplaySum PROTO, ptrPrompt:PTR BYTE,; prompt string theSum:DWORD; sum of the array The sum.inc file contains prototypes for external functions that are not in the Irvine32 library:
83
83 Main.asm TITLE Integer Summation Program INCLUDE sum.inc.code main PROC call Clrscr INVOKE PromptForIntegers, ADDR prompt1, ADDR array, Count... call Crlf INVOKE ExitProcess,0 main ENDP END main
85
85 Example: ArraySum Program Let's review the ArraySum program from Chapter 5. Each of the four white rectangles will become a module.
86
86 AddTwo Procedure (1 of 2) AddTwo PROC, val1:DWORD, val2:DWORD mov eax,val1 add eax,val2 ret AddTwo ENDP Recall the AddTwo Procedure
87
87 AddTwo Procedure (2 of 2) AddTwo PROC, val1:DWORD, val2:DWORD push ebp mov ebp, esp mov eax,val1 add eax,val2 leave ret 8 AddTwo ENDP MASM generates the following code when we assemble AddTwo (from the previous panel): mov esp,ebp pop ebp The LEAVE instruction is shorthand for: p.229
88
88 Passing by value When a procedure argument is passed by value, a copy of a 16-bit or 32-bit integer is pushed on the stack. Example:.data myData WORD 1000h.code main PROC INVOKE Sub1, myData push myData call Sub1 MASM generates the following code:
89
89 Passing by reference When an argument is passed by reference, its address is pushed on the stack. Example:.data myData WORD 1000h.code main PROC INVOKE Sub1, ADDR myData push OFFSET myData call Sub1 MASM generates the following code:
90
90 Statistics for midterm Average=52.82, Std. dev.=18.01
91
91
92
92 Stack Parameters Register vs. Stack Parameters INVOKE Directive PROC Directive PROTO Directive Passing by Value or by Reference Parameter Classifications Example: Exchanging Two Integers Trouble-Shooting Tips
93
93 Recursion What is recursion? Recursively Calculating a Sum Calculating a Factorial
94
94 Recursively Calculating a Sum CalcSum PROC cmp ecx,0; check counter value jz L2; quit if zero add eax,ecx; otherwise, add to sum dec ecx; decrement counter call CalcSum; recursive call L2: ret CalcSum ENDP The CalcSum procedure recursively calculates the sum of an array of integers. Receives: ECX = count. Returns: EAX = sum Stack frame: View the complete programcomplete program
95
95 Inspect Individual Modules Main PromptForIntegers ArraySum DisplaySum Custom batch fileCustom batch file for assembling and linking.
96
96 Sample Program output Enter a signed integer: -25 Enter a signed integer: 36 Enter a signed integer: 42 The sum of the integers is: +53
97
97 Stack Frames Memory Models Language Specifiers Explicit Access to Stack Parameters Passing Arguments by Reference Creating Local Variables
98
98 Your turn... Create a procedure named Difference that subtracts the first argument from the second one. Following is a sample call: push 14; first argument push 30; second argument call Difference; EAX = 16 Difference PROC push ebp mov ebp,esp mov eax,[ebp + 8]; second argument sub eax,[ebp + 12]; first argument pop ebp ret 8 Difference ENDP
99
99 PROC examples ReadFile PROC, pBuffer:PTR BYTE LOCAL fileHandle:DWORD... ReadFile ENDP Swap PROC, pValX:PTR DWORD, pValY:PTR DWORD... Swap ENDP
100
100 Trouble-Shooting Tips Save and restore registers when they are modified by a procedure. –Except a register that returns a function result When using INVOKE, be careful to pass a pointer to the correct data type. For example, MASM cannot distinguish between a DWORD argument and a PTR BYTE argument. Do not pass an immediate value to a procedure that expects a reference parameter. Dereferencing its address will likely cause a general- protection fault.
101
101 Recursively calculating a sum mov ecx, 5 mov eax, 0 call CalcSum CalcSum PROC cmp ecx,0; check counter value jz L2; quit if zero add eax,ecx; otherwise, add to sum dec ecx; decrement counter call CalcSum; recursive call L2: ret CalcSum ENDP The CalcSum procedure recursively calculates the sum of 1 to n. Receives: ECX = count. Returns: EAX = sum Stack frame:
102
102 PROC examples FillArray PROC, pArray:PTR BYTE, fillVal:BYTE arraySize:DWORD mov ecx,arraySize mov esi,pArray mov al,fillVal L1:mov [esi],al inc esi loop L1 ret FillArray ENDP FillArray receives a pointer to an array of bytes, a single byte fill value that will be copied to each element of the array, and the size of the array.
103
103 LOCAL directive LOCAL flagVals[20]:BYTE; array of bytes LOCAL pArray:PTR WORD; pointer to an array myProc PROC,; procedure p1:PTR WORD; parameter LOCAL t1:BYTE,; local variables t2:WORD, t3:DWORD, t4:PTR DWORD Examples:
104
104 Program design using procedures Top-Down Design (functional decomposition) involves the following: –design your program before starting to code –break large tasks into smaller ones –use a hierarchical structure based on procedure calls –test individual procedures separately
105
105 Integer summation program (1 of 4) Main steps: Prompt user for multiple integers Calculate the sum of the array Display the sum Spec.: Write a program that prompts the user for multiple 32-bit integers, stores them in an array, calculates the sum of the array, and displays the sum on the screen.
106
106 Procedure design (2 of 4) Main Clrscr; clear screen PromptForIntegers WriteString; display string ReadInt ; input integer ArraySum ; sum the integers DisplaySum WriteString; display string WriteInt; display integer
107
107 Structure chart (3 of 4)
108
108 PromptForIntegers ;--------------------------------------------------- PromptForIntegers PROC ; ; Prompts the user for an array of integers, and ; fills the array with the user's input. ; Receives: ESI points to the array, ; ECX = array size ; Returns: nothing ;-------------------------------------------------- pushad; save all registers mov edx,OFFSET prompt1 ; address of the prompt cmp ecx,0 ; array size <= 0? jle L2 ; yes: quit
109
109 PromptForIntegers L1: call WriteString; display string call ReadInt; read integer into EAX call Crlf ; go to next output line mov [esi],eax; store in array add esi,4; next integer loop L1 L2: popad; restore all registers ret PromptForIntegers ENDP
110
110 PromptForIntegers ;--------------------------------------------------- DisplaySum PROC ; Displays the sum on the screen ; Receives: EAX = the sum ; Returns: nothing ;--------------------------------------------------- push edx mov edx,OFFSET prompt2 ; display message call WriteString call WriteInt ; display EAX call Crlf pop edx ret DisplaySum ENDP
111
111 Code fragment IntegerCount = 3; array size.data prompt1 BYTE "Enter a signed integer: ",0 prompt2 BYTE "The sum of the integers is: ",0 array DWORD IntegerCount DUP(?).code main PROC call Clrscr mov esi,OFFSET array mov ecx,IntegerCount call PromptForIntegers call ArraySum call DisplaySum exit main ENDP
112
112 Sample output (4 of 4) Enter a signed integer: 550 Enter a signed integer: -23 Enter a signed integer: -96 The sum of the integers is: +431
113
113
114
114
115
115 Example: reversing a string Use a loop with indexed addressing Push each character on the stack Start at the beginning of the string, pop the stack in reverse order, insert each character into the string Source code Q: Why must each character be put in EAX before it is pushed? Because only word (16-bit) or doubleword (32-bit) values can be pushed on the stack.
116
116 Your turn... Using the String Reverse program as a starting point, #1: Modify the program so the user can input a string of up to 50 characters. #2: Modify the program so it inputs a list of 32-bit integers from the user, and then displays the integers in reverse order.
117
117 Your Turn... Write a program that does the following: –Assigns integer values to EAX, EBX, ECX, EDX, ESI, and EDI –Uses PUSHAD to push the general-purpose registers on the stack –Using a loop, the program pops each integer from the stack and displays it on the screen
118
118 Defining and using procedures Creating Procedures Documenting Procedures Example: SumOf Procedure CALL and RET Instructions Nested Procedure Calls Local and Global Labels Procedure Parameters Flowchart Symbols USES Operator
119
119 Your turn... Draw a flowchart that expresses the following pseudocode: input exam grade from the user if( grade > 70 ) display "Pass" else display "Fail" endif
120
120... (Solution)
121
121 Your turn... Modify the flowchart in the previous slide to allow the user to continue to input exam scores until a value of – 1 is entered
122
122 When not to push a register SumOf PROC ; sum of three integers push eax; line 1 add eax,ebx; line 2 add eax,ecx; line 3 pop eax; line 4 ret SumOf ENDP The sum of the three registers is stored in EAX on line (3), but the POP instruction replaces it with the starting value of EAX on line (4):
123
123 Flowchart symbols The following symbols are the basic building blocks of flowcharts:
124
124 Flowchart for the ArraySum Procedure
125
125 Overview Stack Frames (a communication protocol between high-level-language procedures) Stack Parameters (passing by value, passing by reference, memory model and language specifiers) Local Variables (creating and initializing on the stack, scope and lifetime, LOCAL) Recursion Related directives: INVOKE, PROC, PROTO Creating Multimodule Programs
126
126 WriteStackFrame Procedure Displays contents of current stack frame WriteStackFrame PROTO, numParam:DWORD, ; # of passed parameters numLocalVal: DWORD, ; # of DWordLocal ; variables numSavedReg: DWORD ; # of saved registers
127
127 WriteStackFrame Example main PROC mov eax, 0EAEAEAEAh mov ebx, 0EBEBEBEBh INVOKE aProc, 1111h, 2222h exit main ENDP aProc PROC USES eax ebx, x: DWORD, y: DWORD LOCAL a:DWORD, b:DWORD PARAMS = 2 LOCALS = 2 SAVED_REGS = 2 mov a,0AAAAh mov b,0BBBBh INVOKE WriteStackFrame, PARAMS, LOCALS, SAVED_REGS
128
128 WriteStackFrame Example Stack Frame 00002222 ebp+12 (parameters) 00001111 ebp+8 (parameters) 00401083 ebp+4 (return address) 0012FFF0 ebp+0 (saved ebp) ebp 0000AAAA ebp-4 (local variable) 0000BBBB ebp-8 (local variable) EAEAEAEA ebp-12 (saved register) EBEBEBEB ebp-16 (saved register) esp
129
129 Parameter classifications An input parameter is data passed by a calling program to a procedure. –The called procedure is not expected to modify the corresponding parameter variable, and even if it does, the modification is confined to the procedure itself. An input-output parameter represents a value passed as input to a procedure, which the procedure may modify. The same parameter is then able to return the changed data to the calling program. An output parameter is created by passing a pointer to a variable when a procedure is called. The procedure does not use any existing data from the variable, but it fills in a new value before it returns.
130
130 Example: exchanging two integers Swap PROC USES eax esi edi, pValX:PTR DWORD, ; pointer to first integer pValY:PTR DWORD ; pointer to second integer mov esi,pValX ; get pointers mov edi,pValY mov eax,[esi] ; get first integer xchg eax,[edi] ; exchange with second mov [esi],eax ; replace first integer ret ; MASM changes it to ret 8 due to PROC Swap ENDP The Swap procedure exchanges the values of two 32-bit integers. pValX and pValY do not change values, but the integers they point to are modified.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.