(!! loop-unroll-code `(sum_loop ;; Subroutine setup (pushl %ebp) ; 0: Save superior frame pointer (rrmovl %esp %ebp) ; 2: Set frame pointer (pushl %ebx) ; Save callee-save registers on stack (pushl %edi) ; Save callee-save registers on stack (pushl %esi) ; Save callee-save registers on stack (mrmovl 8(%ebp) %ebx) ; Get (mrmovl 12(%ebp) %edx) ; Get pointer to array of number to add (irmovl 1 %edi) ; Constant 1 (irmovl 4 %esi) ; Constant 4 (xorl %eax %eax) ; Zero register initial_test (andl %ebx %ebx) ; N = 0 ? (je sum_loop_leave) ; Leave if zero loop (mrmovl 0(%edx) %ecx) ; Get element from array (addl %ecx %eax) ; Accumulate to %eax (addl %esi %edx) ; Increment pointer ;; Un-rolled Instructions here... (subl %edi %ebx) ; n-1 (jne loop) ;; Subroutine leave sum_loop_leave (popl %esi) (popl %edi) (popl %ebx) (rrmovl %ebp %esp) ; Restore stack pointer (popl %ebp) ; Restore previous frame pointer (ret) ; Subroutine return end_sum_loop ;; Main program (align 4) ; Align to 16-byte address (pos 80) ; Position at 80 main ; "main" program (irmovl stack %esp) ; Initialize stack pointer (%esp) (rrmovl %esp %ebp) ; Initialize frame pointer (%ebp) (irmovl stack %eax) ; Location of array (pushl %eax) ; Push argument on stack (irmovl 5 %eax) ; : (pushl %eax) ; Push argument on stack (call sum_loop) ; Call Fibonacci subroutine return_here (popl %ebx) ; Restore local stack position (popl %ebx) ; Restore local stack position (halt) ; Halt end_of_main ;; Stack (pos 1028) ; 1028: Assemble position stack ; 1028: Thus, "stack" has value 1028 ;; Some data... (dword 35) (dword 300) (dword 7) (dword 1000) (dword 600) (dword 0) (dword 0) (dword 0) )) (y86-prog (@ loop-unroll-code)) (! location 0) (! symbol-table (hons-shrink-alist (y86-symbol-table (@ loop-unroll-code) (@ location) 'symbol-table) 'shrunk-symbol-table)) ; The function Y86-ASM assembles a program into a memory image. (!! init-mem (hons-shrink-alist (y86-asm (@ loop-unroll-code) (@ location) (@ symbol-table) 'sum_loop) 'shrunk_sum_loop)) ; Initialize the Y86 state, note we need initial values for various ; registers. Here, we clear the registers (not really necessary) and ; the memory (m86-clear-regs x86-32) ; Clear registers (m86-clear-mem x86-32 8192) ; Clear memory location 0 to 8192 (! init-pc (cdr (hons-get 'main (@ symbol-table)))) (! y86-status nil) ; Initial value for the Y86 status register (init-y86-state (@ y86-status) ; Y86 status (@ init-pc) ; Initial program counter nil ; Initial registers, if NIL, then all zeros nil ; Initial flags, if NIL, then all zeros (@ init-mem) ; Initial memory x86-32 ) ; Lines that can be typed that just shows the Y86 machine status and ; some of the memory after single stepping. ; (y86-step x86-32) (m32-get-regs-and-flags x86-32) ; (rmb 4 (rgfi *mr-esp* x86-32) x86-32) ; Step ISA 10,000,000,000 (about 20 minutes) steps or to HALT. (time$ (y86 x86-32 200)) (m32-get-regs-and-flags x86-32)