procedures
home
PROC Intro
Problems can be divided into smaller tasks to make them more manageable A PROC is the ASM equivalent of a C++ function sample PROC . . ret sample ENDP CALL instruction calls a procedure pushes address of next instruction onto the stack copies address of called procedure into EIP RET instruction returns from a procedure pops top of stack into EIP
DOCUMENTING Procs Describe all tasks accomplished by the procedure. Receives: list input parameters; state their usage and requirements. Returns: describe values returned by the procedure. Requires: Optional - preconditions that must be satisfied before called. ;--------------------------------------------------------- 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
0000025 is the offset of the instruction following the CALL instruction 00000040 is the offset of the first instruction inside MySub main PROC 00000020 call MySub ; 40 to eip, 25 to stack 00000025 mov eax,ebx . . main ENDP MySub PROC 00000040 mov eax,edx . . ret ; pop stack, 25 to eip MySub ENDP
Procedures can call other procedures and so on... return addresses are pushed onto the stack as calls are made ... and popped off as each returns

Making a Proc general
Parameters: make procedures flexible ========== Registers are an accepted way to pass parameters in assembly, but one must be VERY careful. The stack can also be used. A good procedure might be usable in many different programs but NOT if it refers to specific variable names declared elsewhere...
The ArraySum procedure calculates the sum of an array. It makes two references to specific variable names: 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 (why 4?) loop L1 ; repeat for array size (set by caller in ECX) mov theSum, eax ; store the sum ret ArraySum ENDP
This version of ArraySum returns the sum of ANY doubleword array Address of array passed in ESI. The array count is passed in ECX The sum is returned in EAX: ArraySum PROC ; Receives: ESI points to an array of doublewords, ; ECX = number of array elements. ; Returns: EAX = sum ;----------------------------------------------------- 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 ret ArraySum ENDP
Using PUSH and the Stack to save & restore the registers ==== ArraySum PROC ; Receives: ESI points to an array of doublewords, ; ECX = number of array elements. ; Returns: EAX = sum ;----------------------------------------------------- push esi ; save! push ecx ; save! 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 ; restore! pop esi ; restore! ret ArraySum ENDP

Code - summing with 3 procs

TITLE Integer Summation Program (Sum2.asm)

; This program prompts the user for three integers, stores them in an array, calculates the sum of the ; array, and displays the sum. Last update: 06/01/2006 INCLUDE Irvine32.inc INTEGER_COUNT = 3 .data str1 BYTE "Enter a signed integer: ",0 str2 BYTE "The sum of the integers is: ",0 array DWORD INTEGER_COUNT DUP(?) .code main PROC call Clrscr mov esi, OFFSET array mov ecx, INTEGER_COUNT call PromptForIntegers call ArraySum call DisplaySum exit main ENDP ;----------------------------------------------------- PromptForIntegers PROC USES ecx edx esi ; ; Prompts the user for an arbitrary number of integers ; and inserts the integers into an array. ; Receives: ESI points to the array, ECX = array size ; Returns: nothing ;----------------------------------------------------- mov edx, OFFSET str1 ; "Enter a signed integer" 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, TYPE DWORD ; next integer loop L1 ret PromptForIntegers ENDP ;----------------------------------------------------- ArraySum PROC USES esi ecx ; ; Calculates the sum of an array of 32-bit integers. ; Receives: ESI points to the array, ECX = number of array elements ; Returns: EAX = sum of the array elements ;----------------------------------------------------- mov eax, 0 ; set the sum to zero L1: add eax, [esi] ; add each integer to sum add esi, TYPE DWORD ; point to next integer loop L1 ; repeat for array size ret ; sum is in EAX ArraySum ENDP ;----------------------------------------------------- DisplaySum PROC USES edx ; ; Displays the sum on the screen ; Receives: EAX = the sum ; Returns: nothing ;----------------------------------------------------- mov edx,OFFSET str2 ; "The sum of the..." call WriteString call WriteInt ; display EAX call Crlf ret DisplaySum ENDP END main

Recursion

TITLE Sum of Integers (CSum.asm)

; This program demonstrates recursion as it sums the integers 1-n INCLUDE Irvine32.inc .code main PROC mov ecx, 10 ; count = 10 mov eax, 0 ; holds the sum call CalcSum ; calculate sum L1: call WriteDec ; display eax call Crlf exit main ENDP ;-------------------------------------------------------- CalcSum PROC ; Calculates the sum of a list of integers ; Receives: ECX = count ; Returns: EAX = sum ;-------------------------------------------------------- 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 END Main

Encryption

TITLE Encryption Program (Encrypt.asm)

; This program demonstrates simple symmetric encryption using the XOR instruction. INCLUDE Irvine32.inc KEY = 239 ; any value between 1-255 BUFMAX = 128 ; maximum buffer size .data sPrompt BYTE "Enter the plain text: ",0 sEncrypt BYTE "Cipher text: ",0 sDecrypt BYTE "Decrypted: ",0 buffer BYTE BUFMAX dup(0) bufSize DWORD ? .code main PROC call InputTheString ; input the plain text call TranslateBuffer ; encrypt the buffer mov edx,OFFSET sEncrypt ; display encrypted message call DisplayMessage call TranslateBuffer ; decrypt the buffer mov edx,OFFSET sDecrypt ; display decrypted message call DisplayMessage exit main ENDP InputTheString PROC ; Asks user to enter string from the keyboard. Save string and its length ; in variables. Receives: nothing. Returns: nothing pushad mov edx,offset sPrompt ; display a prompt call WriteString mov ecx,BUFMAX ; maximum character count mov edx,offset buffer ; point to the buffer call ReadString ; input the string mov bufSize,eax ; save the length call Crlf popad ret InputTheString ENDP ;----------------------------------------------------- DisplayMessage PROC ; ; Display the encrypted or decrypted message. ; Receives: EDX points to the message Returns: nothing ;----------------------------------------------------- pushad call WriteString mov edx,offset buffer ; display the buffer call WriteString call Crlf call Crlf popad ret DisplayMessage ENDP ;----------------------------------------------------- TranslateBuffer PROC ; ; Translates the string by exclusive-ORing each byte ; with the same integer.; Receives: nothing. Returns: nothing ;----------------------------------------------------- pushad mov ecx,bufSize ; loop counter mov esi,0 ; index 0 in buffer L1: xor buffer[esi],KEY ; translate a byte inc esi ; point to next byte loop L1 popad ret TranslateBuffer ENDP END main