assembly: procedures
jbwyatt.com

.. 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