.. 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
USES Lists & saves the registers that will be saved
====
ArraySum PROC USES ESI, ECX
; 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
MASM actually generates the following code:
ArraySum PROC USES ESI, ECX
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
.. Example code: summing - 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
.. Example code: summing elements - 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
.. Example code: 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