/*
 * COSC 065 - Hardware Systems
 * D.W. Brylow 
 * Intel x86 assembly demo.
 */

.section .rodata
FMT:    .string "%d\n"
        
.section .text
.globl main

/* int main()
 *  {
 *       printf("%d\n", foo(4) );
 *       
 *  }
 */ 
        
main:
   pushl  %ebp            /* Function prologue saves caller base pointer */
   movl   %esp, %ebp      /* Stack pointer becomes new base pointer      */

   pushl  $4              /* Arguments get pushed on stack               */
   call   foo             /* Call foo(4)                                 */

   pushl  %eax            /* Return value is in %eax                     */
   pushl  $FMT            /* Push address of format string               */
   call   printf          /* Call printf("%d\n", foo(4))                 */
        
   movl   %ebp, %esp      /* Function epilogue pops stack                */
   popl   %ebp            /* Restore caller base pointer                 */
   ret                    /* Caller return address on top of stack       */

                
/*  int foo(int x)
 *  {
 *       int y;
 *       int z;
 *       y = 5;
 *       z = x + y;
 *       return z;
 *  }
 */

foo:
   pushl  %ebp            /* Function prologue saves caller base pointer */
   movl   %esp, %ebp      /* Stack pointer becomes new base pointer      */
   subl   $8, %esp        /* Allocate space for two locals (y and z)     */
      
   movl   $5, -8(%ebp)    /* Initialize local int y to 5                 */
   movl   -8(%ebp), %eax  /* Move y into accumulator,                    */
   addl   8(%ebp), %eax   /*  add to it passed parameter x               */
   movl   %eax, -4(%ebp)  /* Store result in local int z                 */
   movl   -4(%ebp), %eax  /* Move z into return value register           */

   movl   %ebp, %esp      /* Function epilogue pops stack                */
   popl   %ebp            /* Restore caller base pointer                 */
   ret                    /* Caller return address on top of stack       */

