.. PROC intro
Problems can be divided into smaller tasks to make them more manageable
A PROC is the ASM equivalent of a C++ function or C# method
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.
;---------------------------------------------------------
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.
;---------------------------------------------------------
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
.. PROC ... ENDP
- way to organize code
- isolate and re-use functionality
- can pass parameters vis stack or registers
- don't use memory to pass parameters!
- DOCUMENT!!
==============================================
call Traffic ; transfers control to the proc
--------------
Traffic PROC
; code goes here
ret ; return to caller
Traffic ENDP
.. 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...
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
.. 16 bit ASM: temperature convert
; centigrade (celsius) to fahrenheit calculation and vice-versa.
; it may not be accurate, because of integer division.
; this program prints out the result in binary code.
; to see result in hexadecimal or decimal form click vars.
name "celsi"
org 100h
jmp START
; DATA
tc db 10 ; t celsius.
tf db 0 ; t fahrenheit.
result1 db ? ; result in fahrenheit.
result2 db ? ; result in celsius.
START:
; convert celsius to fahrenheit according
; to this formula: f = c * 9 / 5 + 32
mov cl, tc
mov al, 9
imul cl
mov cl, 5
idiv cl
add al, 32
mov result1, al
mov bl, result1
call print ; print bl
; convert fahrenheit to celsius according
; to this formula: c = (f - 32) * 5 / 9
mov cl, tf
sub cl, 32
mov al, 5
imul cl
mov cl, 9
idiv cl
mov result2, al
; call the PRINT PROCEDURE
mov bl, result2
call Print ; print bl
; wait for any key press...
mov ah, 0
int 16h
ret ; return to the operating system.
;=========================================
; procedure prints the binary value of bl
Print PROC
; save all
pusha
; print result in binary:
mov cx, 8
p1: mov ah, 2
mov dl, '0'
test bl, 10000000b ;test first bit.
jz zero
mov dl, '1'
zero: int 21h ;print function.
shl bl, 1
loop p1
; print binary suffix:
mov dl, 'b'
int 21h
; print carrige return and new line:
mov dl, 0Dh
int 21h
mov dl, 0Ah
int 21h
;restore all
popa
ret ; return to the caller
Print ENDP
;==========================================
.. Create a PROC
Build a procedure called "DoIt" that will take whatever is in the AL register,
ADD 10, and PRINT it.
TELL if there is unsigned overflow!!!
INCLUDE emu8086.inc
org 100h
mov al, 100
call DoIt
mov al, 0
call DoIt
mov al, 254
call DoIt
ret
DoIt proc
add al, 10
jc BIG
mov ah, 0
call PRINT_NUM
PRINTN
jmp R
BIG:
PRINTN "Bigg"
R:
ret
DoIt ENDP
DEFINE_PRINT_NUM ; prints AX signed
DEFINE_PRINT_NUM_UNS ; prints AX unsigned
END