CSC231 List of All Class Demo Files 2012

From dftwiki3
Jump to: navigation, search

--D. Thiebaut 07:58, 26 November 2012 (EST)
Updated --D. Thiebaut 10:09, 14 December 2012 (EST)



Contents

Listings from ~231a/handout

Scripts

nasmld


#! /bin/bash
set -e      # exit on error
filename=$(basename "$1")
extension="${filename##*.}"
filename="${filename%.*}"
nasm -f elf -F stabs $filename.asm
ld -o $filename -melf_i386 $filename.o






Asm Files

asm_io.asm


;
; file: asm_io.asm
; Assembly I/O routines
; To assemble for DJGPP
;   nasm -f coff -d COFF_TYPE asm_io.asm
; To assemble for Borland C++ 5.x
;   nasm -f obj -d OBJ_TYPE asm_io.asm
; To assemble for Microsoft Visual Studio
;   nasm -f win32 -d COFF_TYPE asm_io.asm
; To assemble for Linux
;   nasm -f elf -d ELF_TYPE asm_io.asm

%define NL 10
%define CF_MASK 00000001h
%define PF_MASK 00000004h
%define AF_MASK 00000010h
%define ZF_MASK 00000040h
%define SF_MASK 00000080h
%define DF_MASK 00000400h
%define OF_MASK 00000800h


;
; Linux C doesn't put underscores on labels
;
;;;  %ifdef ELF_TYPE
  %define _scanf   scanf
  %define _printf  printf
  %define _getchar getchar
  %define _putchar putchar
  %define _fputs   fputs
;;; %endif

%ifdef OBJ_TYPE
segment .data public align=4 class=data use32
%else
segment .data
%endif

int_format	    db  "%i", 0
string_format       db  "%s", 0
reg_format	    db  "Register Dump # %d", NL
		    db  "EAX = %.8X EBX = %.8X ECX = %.8X EDX = %.8X", NL
                    db  "ESI = %.8X EDI = %.8X EBP = %.8X ESP = %.8X", NL
                    db  "EIP = %.8X FLAGS = %.4X %s %s %s %s %s %s %s", NL
	            db  0
carry_flag	    db  "CF", 0
zero_flag	    db  "ZF", 0
sign_flag	    db  "SF", 0
parity_flag	    db	"PF", 0
overflow_flag	    db	"OF", 0
dir_flag	    db	"DF", 0
aux_carry_flag	    db	"AF", 0
unset_flag	    db	"  ", 0
mem_format1         db  "Memory Dump # %d Address = %.8X", NL, 0
mem_format2         db  "%.8X ", 0
mem_format3         db  "%.2X ", 0
stack_format        db  "Stack Dump # %d", NL
	            db  "EBP = %.8X ESP = %.8X", NL, 0
stack_line_format   db  "%+4d  %.8X  %.8X", NL, 0
math_format1        db  "Math Coprocessor Dump # %d Control Word = %.4X"
                    db  " Status Word = %.4X", NL, 0
valid_st_format     db  "ST%d: %.10g", NL, 0
invalid_st_format   db  "ST%d: Invalid ST", NL, 0
empty_st_format     db  "ST%d: Empty", NL, 0
   
;
; code is put in the _TEXT segment
;
%ifdef OBJ_TYPE
segment text public align=1 class=code use32
%else
segment .text
%endif
	global	read_int, print_int, print_string, read_char, print_hex
	global  print_char, print_nl, sub_dump_regs, sub_dump_mem
        global  sub_dump_math, sub_dump_stack
        extern  _scanf, _printf, _getchar, _putchar, _fputs

read_int:
	enter	4,0
	pusha
	pushf

	lea	eax, [ebp-4]
	push	eax
	push	dword int_format
	call	_scanf
	pop	ecx
	pop	ecx
	
	popf
	popa
	mov	eax, [ebp-4]
	leave
	ret

print_int:
	enter	0,0
	pusha
	pushf

	push	eax
	push	dword int_format
	call	_printf
	pop	ecx
	pop	ecx

	popf
	popa
	leave
	ret

print_hex:
	enter	0,0
	pusha
	pushf

	push	eax
	push	dword mem_format2
	call	_printf
	pop	ecx
	pop	ecx

	popf
	popa
	leave
	ret

print_string:
	enter	0,0
	pusha
	pushf

	push	eax
	push    dword string_format
	call	_printf
	pop	ecx
	pop	ecx

	popf
	popa
	leave
	ret

read_char:
	enter	4,0
	pusha
	pushf

	call	_getchar
	mov	[ebp-4], eax

	popf
	popa
	mov	eax, [ebp-4]
	leave
	ret

print_char:
	enter	0,0
	pusha
	pushf

	push	eax
	call	_putchar
	pop	ecx

	popf
	popa
	leave
	ret


print_nl:
	enter	0,0
	pusha
	pushf

	push	dword 10	; 10 == ASCII code for \n
	call	_putchar
	pop	ecx

	popf
	popa
	leave
	ret


sub_dump_regs:
	enter   4,0
	pusha
	pushf
	mov     eax, [esp]      ; read FLAGS back off stack
	mov	[ebp-4], eax    ; save flags

;
; show which FLAGS are set
;
	test	eax, CF_MASK
	jz	cf_off
	mov	eax, carry_flag
	jmp	short push_cf
cf_off:
	mov	eax, unset_flag
push_cf:
	push	eax

	test	dword [ebp-4], PF_MASK
	jz	pf_off
	mov	eax, parity_flag
	jmp	short push_pf
pf_off:
	mov	eax, unset_flag
push_pf:
	push	eax

	test	dword [ebp-4], AF_MASK
	jz	af_off
	mov	eax, aux_carry_flag
	jmp	short push_af
af_off:
	mov	eax, unset_flag
push_af:
	push	eax

	test	dword [ebp-4], ZF_MASK
	jz	zf_off
	mov	eax, zero_flag
	jmp	short push_zf
zf_off:
	mov	eax, unset_flag
push_zf:
	push	eax

	test	dword [ebp-4], SF_MASK
	jz	sf_off
	mov	eax, sign_flag
	jmp	short push_sf
sf_off:
	mov	eax, unset_flag
push_sf:
	push	eax

	test	dword [ebp-4], DF_MASK
	jz	df_off
	mov	eax, dir_flag
	jmp	short push_df
df_off:
	mov	eax, unset_flag
push_df:
	push	eax

	test	dword [ebp-4], OF_MASK
	jz	of_off
	mov	eax, overflow_flag
	jmp	short push_of
of_off:
	mov	eax, unset_flag
push_of:
	push	eax

	push    dword [ebp-4]   ; FLAGS
	mov	eax, [ebp+4]
	sub	eax, 10         ; EIP on stack is 10 bytes ahead of orig
	push	eax             ; EIP
	lea     eax, [ebp+12]
	push    eax             ; original ESP
	push    dword [ebp]     ; original EBP
        push    edi
        push    esi
	push    edx
	push	ecx
	push	ebx
	push	dword [ebp-8]   ; original EAX
	push	dword [ebp+8]   ; # of dump
	push	dword reg_format
	call	_printf
	add	esp, 76
	popf
	popa
	leave
	ret     4

sub_dump_stack:
	enter   0,0
	pusha
	pushf

	lea     eax, [ebp+20]
	push    eax             ; original ESP
	push    dword [ebp]     ; original EBP
	push	dword [ebp+8]   ; # of dump
	push	dword stack_format
	call	_printf
	add	esp, 16

	mov	ebx, [ebp]	; ebx = original ebp
	mov	eax, [ebp+16]   ; eax = # dwords above ebp
	shl	eax, 2          ; eax *= 4
	add	ebx, eax	; ebx = & highest dword in stack to display
	mov	edx, [ebp+16]
	mov	ecx, edx
	add	ecx, [ebp+12]
	inc	ecx		; ecx = # of dwords to display

stack_line_loop:
	push	edx
	push	ecx		; save ecx & edx

	push	dword [ebx]	; value on stack
	push	ebx		; address of value on stack
	mov	eax, edx
	sal	eax, 2		; eax = 4*edx
	push	eax		; offset from ebp
	push	dword stack_line_format
	call	_printf
	add	esp, 16

	pop	ecx
	pop	edx

	sub	ebx, 4
	dec	edx
	loop	stack_line_loop

	popf
	popa
	leave
	ret     12


sub_dump_mem:
	enter	0,0
	pusha
	pushf

	push	dword [ebp+12]
	push	dword [ebp+16]
	push	dword mem_format1
	call	_printf
	add	esp, 12		
	mov	esi, [ebp+12]      ; address
	and	esi, 0FFFFFFF0h    ; move to start of paragraph
	mov	ecx, [ebp+8]
	inc	ecx
mem_outer_loop:
	push	ecx
	push	esi
	push	dword mem_format2
	call	_printf
	add	esp, 8

	xor	ebx, ebx
mem_hex_loop:
	xor	eax, eax
	mov	al, [esi + ebx]
	push	eax
	push	dword mem_format3
	call	_printf
	add	esp, 8
	inc	ebx
	cmp	ebx, 16
	jl	mem_hex_loop
	
	mov	eax, '"'
	call	print_char
	xor	ebx, ebx
mem_char_loop:
	xor	eax, eax
	mov	al, [esi+ebx]
	cmp	al, 32
	jl	non_printable
	cmp	al, 126
	jg	non_printable
	jmp	short mem_char_loop_continue
non_printable:
	mov	eax, '?'
mem_char_loop_continue:
	call	print_char

	inc	ebx
	cmp	ebx, 16
	jl	mem_char_loop

	mov	eax, '"'
	call	print_char
	call	print_nl

	add	esi, 16
	pop	ecx
	loop	mem_outer_loop

	popf
	popa
	leave
	ret	12

; function sub_dump_math
;   prints out state of math coprocessor without modifying the coprocessor
;   or regular processor state
; Parameters:
;  dump number - dword at [ebp+8]
; Local variables:
;   ebp-108 start of fsave buffer
;   ebp-116 temp double
; Notes: This procedure uses the Pascal convention.
;   fsave buffer structure:
;   ebp-108   control word
;   ebp-104   status word
;   ebp-100   tag word
;   ebp-80    ST0
;   ebp-70    ST1
;   ebp-60    ST2 ...
;   ebp-10    ST7
;
sub_dump_math:
	enter	116,0
	pusha
	pushf

	fsave	[ebp-108]	; save coprocessor state to memory
	mov	eax, [ebp-104]  ; status word
	and	eax, 0FFFFh
	push	eax
	mov	eax, [ebp-108]  ; control word
	and	eax, 0FFFFh
	push	eax
	push	dword [ebp+8]
	push	dword math_format1
	call	_printf
	add	esp, 16
;
; rotate tag word so that tags in same order as numbers are
; in the stack
;
	mov	cx, [ebp-104]	; ax = status word
	shr	cx, 11
	and	cx, 7           ; cl = physical state of number on stack top
	mov	bx, [ebp-100]   ; bx = tag word
	shl     cl,1		; cl *= 2
	ror	bx, cl		; move top of stack tag to lowest bits

	mov	edi, 0		; edi = stack number of number
	lea	esi, [ebp-80]   ; esi = address of ST0
	mov	ecx, 8          ; ecx = loop counter
tag_loop:
	push	ecx
	mov	ax, 3
	and	ax, bx		; ax = current tag
	or	ax, ax		; 00 -> valid number
	je	valid_st
	cmp	ax, 1		; 01 -> zero
	je	zero_st
	cmp	ax, 2		; 10 -> invalid number
	je	invalid_st
	push	edi		; 11 -> empty
	push	dword empty_st_format
	call	_printf
	add	esp, 8
	jmp	short cont_tag_loop
zero_st:
	fldz
	jmp	short print_real
valid_st:
	fld	tword [esi]
print_real:
	fstp	qword [ebp-116]
	push	dword [ebp-112]
	push	dword [ebp-116]
	push	edi
	push	dword valid_st_format
	call	_printf
	add	esp, 16
	jmp	short cont_tag_loop
invalid_st:
	push	edi
	push	dword invalid_st_format
	call	_printf
	add	esp, 8
cont_tag_loop:
	ror	bx, 2		; mov next tag into lowest bits
	inc	edi
	add	esi, 10         ; mov to next number on stack
	pop	ecx
	loop    tag_loop

	frstor	[ebp-108]       ; restore coprocessor state
	popf
	popa
	leave
	ret	4


asm_io.inc


        extern  read_int, print_int, print_string, print_hex
        extern  read_char, print_char, print_nl
        extern  sub_dump_regs, sub_dump_mem, sub_dump_math, sub_dump_stack

%macro  dump_regs 1
        push      dword %1
        call      sub_dump_regs
%endmacro


;
; usage: dump_mem label, start-address, # paragraphs
%macro  dump_mem 3
        push     dword %1
        push     dword %2
        push     dword %3
        call     sub_dump_mem
%endmacro

%macro  dump_math 1
        push     dword %1
        call     sub_dump_math
%endmacro

%macro  dump_stack 3
        push     dword %3
        push     dword %2
        push     dword %1
        call     sub_dump_stack
%endmacro


buggy1.asm


		section	.data
hexChars:	db	"0123456789ABCDEF"

		section	.text
		gobal	_start
_start:
		mov	al,0xf5
		and	al,0x0f		;al <-- 05
		mov	ebx, hexChars 	;ebx <-- address hexChars
		add	bl, al		;ebx <-- hexChars+05
		mov	al,[ebx]	;al <-- '5'

		call	printChar

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;;----------------------------------------------------
;;; printChar: prints char in al to screen
;;;----------------------------------------------------
		section	.data
pc_temp:	db	0
		section	.text
	
printChar:	pushad
		mov	[pc_temp],al     ;store char in string
		mov	eax, 4	         ;print string
		mov	ebx, 1
		mov	ecx, pc_temp
		mov	edx, 1
		int	0x80
	
		popad
		ret


dddTutorial.asm


;;; dddTutorial.asm
;;; YourName
;;; 
;;; this program should be assembled, linked, and debugged
;;; with ddd to figure out the contents of msg1 at the different
;;; phases of the program: phase1, phase2, phase3, phase4,
;;; and phase5
;;;
;;; to assemble and run:
;;;
;;;     nasm -f elf -F  stabs dddTutorial.asm
;;;     ld -melf_i386 -o dddTutorial dddTutorial.o
;;;     ./dddTutorial
;;; -------------------------------------------------------------------
EXIT    equ             1
WRITE   equ             4
STDOUT  equ             1
 
      	;; ------------------------------------------------------------
	;; data areas
	;; ------------------------------------------------------------
 
	section	.data
msg0	db      10, 10, 10, 10, 10
msg1	db	"                               "
	db      10, 10, 10, 10, 10
MSGLEN  equ     $-msg0
	
	;; ------------------------------------------------------------
	;; code area
	;; ------------------------------------------------------------
 
	section	.text
	global	_start
 
_start:
	nop
	nop
	nop
phase1:	
	mov	eax, 0x6c6c6468
	mov	ebx, 0x6064216e  
	mov	ecx, 0x6c687400  
	mov	edx, 0x13070e09  

phase2:	
	mov	dword [msg1], eax
	mov	dword [msg1+4], ebx
	mov	dword [msg1+8], ecx
	mov	dword [msg1+12], edx
	
phase3:	or	dword [msg1], 256
	xor	dword [msg1+4], 0x01010101
	or	dword [msg1+8], 'r'
phase4:	
	or	word [msg1+12], 0x6060
	or	word [msg1+14], 0x6060

phase5:	
	mov	eax, WRITE
	mov	ebx, STDOUT
	mov	ecx, msg0
	mov	edx, MSGLEN
	int	0x80
 
  
	;; exit()
 
	mov	eax,EXIT
	mov	ebx, 0
	int	0x80		; final system call


deleteme.asm


_start:	
	mov	ebx, Pascal	;pass address of array in ebx
	call	init		;store 0 in Pascal array
				;and 1 in first cell

	
	mov	ecx, 10
for:	mov	ebx, Pascal	;pass address of array in ebx
	call	printArray	;print Pascal array

	mov	ebx, Pascal	;pass address of array
	call	nextLine	;compute next line of triangle

	loop	for		; 

;;; exit
	mov	eax, 1
	mov	ebx, 0
	int	0x80
	

	mov	eax, 0x01234567
	mov	ebx, 0x89ABCDEF
	xor	ecx, ecx

	push	ax
	pop	cx

	push	ax
	push	bx
	pop	ecx

	call	next
next:	pop	ecx


dummy.asm


# this
# is
# it


dumpRegs.asm


;;; ---------------------------------------------------------
;;; dumpRegs.asm
;;; D. Thiebaut
;;; 11/13/12
;;; This libary supports several functions that allow the user
;;; to dump the contents of the main 6 registers (eax, ebx, ecx,
;;; edx, esi and edi) to the screen.  Great for debugging without
;;; a debugger.
;;;
;;; Typical output:
;;; 	+-----------------+
;;; 	| eax = 1234 5678 |
;;; 	| ebx = 55FF 55FF |
;;; 	| ecx = FEDC BA98 |
;;; 	| edx = 0000 0000 |
;;; 	| esi = 1111 2222 |
;;; 	| edi = 2222 3333 |
;;; 	+-----------------+
;;; Include in program as follows:
;;; 
;;; 
;;; %include "dumpRegs.asm"
;;; ---------------------------------------------------------

		section	.data
hex		db	"0123456789ABCDEF"
regs		db	"axbxcxdxsidi"
line		db	"+-----------------+", 10
string		db	"| exx = .... .... |", 10
lineLen 	equ	$-string
reg		equ	string+3
word1		equ	string+8

		section	.text

;;; ---------------------------------------------------------
;;; dumpRegs: dumps the contents of the 6 main registers (eax
;;; ebx, ecx, edx, esi and edi) in a box on the screen.
;;; the screen.  Does not modify any register
;;; ---------------------------------------------------------
dumpRegs:	pushad

;;; put all the registers to print in the stack.  The loop
;;; will pop each one, one at a time, once per loop.
	
		push	edi
		push	esi
		push	edx
		push	ecx
		push	ebx
		push	eax

;;; print top bar
		call	printBar
	
;;; prepare to loop 6 times (6 registers )
		mov	ecx, 6
		mov	esi, 0

.for		pop	ebx			;get value of register to convert from stack
		push	ecx			;save loop counter
		lea	eax, [regs + esi*2]	;get address of string representing register
	
		mov	ax, word [eax] 		;ax gets "ax" or "bx" or "cx" or ... "di"
		mov	word[reg], ax		;modify string with name of register
	
		mov	edx, word1 		;edx points to buffer where to store hex digits
						;ebx contains register to convert
		call 	storeDWord		;store hex equivalent of ebx in string
	
		mov	ecx, string 		;print the whole string
		mov	edx, lineLen
		call	printInt80
		inc	esi			;index into register names incremented
		pop	ecx			;get loop counter back
		loop	.for

;;; print bottom bar
		call 	printBar
	
		popad
		ret

;;; ---------------------------------------------------------
;;; storeDWord: gets
;;; 	ebx: register to convert
;;; 	edx: address where to put information
;;; ---------------------------------------------------------
		
storeDWord:	rol	ebx, 16			;bring most sig word in least sig word
		call	storeWord
	
		inc	edx			;make edx skip space in string
	
		rol	ebx, 16			;get lower byte back in least sig pos
		call	storeWord
		
		ret

;;; ---------------------------------------------------------
;;; storeWord: gets
;;;     bx: word to convert
;;; 	edx: address where to put information. edx incremented by 4
;;; ---------------------------------------------------------
storeWord:	rol	bx, 8			;put most sig byte of bx in lower position
		call	storeByte		;and convert it.  Store it in where edx 
						;points to. 
		rol	bx, 8			;same with lower nybble
		call	storeByte
		ret
	
;;; ---------------------------------------------------------
;;; storeByte: gets
;;;     bl: byte to convert
;;; 	edx: address where to store information.  edx incremented by 2 automatically
;;; ---------------------------------------------------------
storeByte:	push	ebx
		push	eax
	
		rol	bl, 4			;get upper nybble in lower position (LSB)
		mov	al, bl			;play with al now
		and	eax, 0x0000000F		;clear all but the least significant nybble
		add	eax, hex		;get ascii in hex array equivalentn to nybble
		mov	al, [eax] 		;hex digit now in bl
		mov	byte [edx], al		;store ascii in string
		inc	edx

		rol	bl, 4			;get lower nybble back
		mov	al, bl			;play with al
		and	eax, 0x0000000F
		add	eax, hex
		mov	al, [eax]
		mov	byte [edx], al
		inc	edx
	
		pop	eax
		pop	ebx
		ret
		
;;; ---------------------------------------------------------
;;; printInt80: prints on the screen the string whose address
;;; is in ecx and length in edx.
;;; does not modify registers
;;; ---------------------------------------------------------
printInt80:	push	eax
		push	ebx
	
		mov	eax, 4
		mov	ebx, 1
		int	0x80
	
		pop	ebx
		pop	eax
		ret
	
;;; ---------------------------------------------------------
;;; printBar: prints the horizontal bar
;;; does not modify registers
;;; ---------------------------------------------------------
printBar:	push	ecx
		push	edx
	
		mov	ecx, line
		mov	edx, lineLen
		call	printInt80
	
		pop	edx
		pop	ecx
		ret


dumpRegs.inc


;;; dumpRegs.inc
		section .data

regNames	db	"| eax = ", "| ebx = ",
		db	"| ecx = ", "| edx = ",
		db	"| edi = ", "| esi = "

;;; holds the line for the top and bottom of the box
line		db	"+------------------+", 10
lineLen		equ	$-line

;;; holds a space
space		db	" "
spaceLen	equ	$-space

;;; holds the formatted bar used at the end of a line
bar		db	" |", 10
barLen		equ	$-bar

;;; a string of all the hex digits
hexChars	db	"0123456789ABCDEF"

;;; holds the value of the current register we're printing
currentReg	dd	0x00000000

;;; used to print the appropriate label
counter		dw	0
	
		section	.text


;;; dumpRegs()
;;; no parameters
;;; prints the contents of the following registers:
;;; 	eax, ebx, ecx, edx, esi, edi
;;; inside of a nicely formatted box.
dumpRegs:	mov	word[counter], 0
	
		call	printLine 		;prints the top of the box

		mov	dword[currentReg], eax 	;print eax's formatted line
		call	printReg

                mov     dword[currentReg], ebx 	;print ebx's formatted line
                call    printReg

                mov     dword[currentReg], ecx 	;print ecx's formatted line
                call    printReg

                mov     dword[currentReg], edx 	;print edx's formatted line
                call    printReg

                mov     dword[currentReg], edi 	;print edi's formatted line
        	call    printReg

                mov     dword[currentReg], esi 	;print esi's formatted line
                call    printReg
	
		call	printLine 		;print the bottom of the box

;exit dumpRegs() 
		ret
	
	

;;; printLine():
;;; no parameters
;;; no modifications
;;; prints "+------------------+" on the screen and
;;; returns to a new line. Uses int 0x80 to print.
;;;
	
printLine:
		push	ecx	;store registers
		push	edx
		
		mov	ecx, line	;the line to print
		mov	edx, lineLen	;the length of that line
		call	printString

;;; restore the values of eax, ebx, ecx, and edx
		pop	edx
		pop	ecx

;;; exit printLine()
		ret

		

;;; printString(String string, int lengthOfString):
;;; parameters:
;;; 	ecx = string to print
;;; 	edx = length of the string to print
;;; modifies: ecx, edx
;;; prints the string passed in through ecx
;;; using int 0x80.
;;; 
printString:
		push	eax	;save eax
		push	ebx	;save ebx
	
		mov	eax, 4	;write
		mov	ebx, 1	;stdout
		int	0x80	;print the string

		pop	ebx	;restore original contents of ebx
		pop	eax	;restore original contents of eax

;;; exit printString()
		ret
	


;;; printSpace():
;;; no parameters
;;; no modifications
;;; prints a space by calling printString().
;;;       
printSpace:	push	edx		;save edx
		push	ecx		;save ecx
	
	        mov     ecx, space 	;move a space
					;into ecx (parameter
					;for printString())
	
		mov     edx, spaceLen	;move the length
					;of that space
					;into edx (parameter
					;for printString()) 
	
		call    printString 	

        	pop	ecx		;restore original
					;value of ecx
		pop	edx		;restore original
					; value of edx

;exit printSpace()
		ret


;;; printLabel():
;;; no parameters
;;; no modifications
;;; prints the first part of each line
;;; by calling printString().
;;; 
;;; i.e.:
;;; | eax = 
;;; 
printLabel:	push    ecx			;save ecx
                push    edx			;save edx

		mov     ecx, regNames		;the list of register names
						;(parameter for printString())	 
		add	cx, word[counter]	;the index of the name of
						;the register we're on

		mov     edx, 8			;the length of each label
						;(parameter for printString()) 
        	call    printString	
	
                pop     edx			;restore original edx
                pop     ecx			;restore original ecx

;exit printLabel()
		ret
	

;;; printEndBar():
;;; no parameters
;;; no modifications
;;; prints " |" (after a register has
;;; been printed out) by calling printString()
;;; 
printEndBar:	push    edx			;save edx
		push	ecx			;save ecx

        	mov     ecx, bar		;move the string with the bar
						;(parameter for printString()) 

        	mov     edx, barLen		;the length of the bar string
						;(parameter for printString()) 
		call    printString 		
		
		pop	ecx			;restore original ecx
		pop	edx			;restore original edx

;exit printEndBar()
		ret


	
;;; printReg(int currentReg)
;;; parameters: currentReg (contains the contents of the current
;;; register that we're printing)
;;; no modifications
;;; 
;;; calls printLabel, printHexWord, printSpace, printHexByte, and
;;; printEndBar to print out the contents of the given register
;;; in blocks like:
;;;
;;; | eax = 0000 00 00 |
;;;
printReg:	call	printLabel 	;print the register label

		call	printHexWord 	;print the first four hex
					;digits 
		call	printSpace	
	
		call	printHexByte 	;print the fifth and sixth
					;hex digits	

        	call    printSpace

                call    printHexByte 	;print the last two hex digits
	
		call	printEndBar 	;print the end of the box (" |")

		add	word[counter], 8 	;increment the counter for
						;label by 8, because each
						;label is 8 bytes long 
; exit printReg()
		ret


	
;;; printHexDigit(int currentReg)
;;; parameters: currentReg (holds the value of the current
;;; register that we're printing)
;;; no modifications
;;; prints a hexdigit (=4 bits) using the int 0x80 method
;;;
printHexDigit:
	
;save each register, as all would be altered by the int 0x80 call
		push	edx
		push	ecx
		push	ebx
		push	eax

;move the contents of the register we're printing (stored in currentReg)
;into eax	
		mov	eax, dword[currentReg]
		rol	eax, 4			;move the next digit to
						;print into al (digits
						;are 4 bits long) 

		mov	dword[currentReg], eax 	;save the changes made
	
		and	eax, 0x0F 		;isolate al

; move hexChars into ecx and use al as an index so that we can
; print the letter/number corresponding to the current digit
		mov	ecx, hexChars
		add	ecx, eax
	
		mov	eax, 4			;write
		mov	ebx, 1			;stdout
		mov	edx, 1			;print 1 character
						;that is 1 byte long
	
		int	0x80			;print the character

;restore the registers to their original values
		pop	eax
		pop	ebx
		pop	ecx
		pop	edx

;exit printHexDigit() 
		ret


	
;;; printHexByte():
;;; parameters: currentReg (holds the value of the current
;;; register that we're printing)
;;; no modifications
;;; calls printHexDigit() twice to print out
;;; the hex value of a byte.
;;; 
printHexByte:	call    printHexDigit
	        call    printHexDigit

;;; exit printHexByte()
        	ret

;;; printHexWord():
;;; parameters: currentReg (holds the value of the current
;;; register that we're printing) 
;;; no modifications
;;; calls printHexByte() twice to print out
;;; the hex value of a word (2 bytes long)
printHexWord:	call    printHexByte
	        call    printHexByte

;;; exit printHexWord()
	        ret


exoFlags.asm


;;; -------------------------------------------------------------------
;;; flagbits.asm
;;; D. Thiebaut
;;; 
;;; a program with several compare instructions and the resulting
;;; flags generated by the ALU.
;;; This program was debugged by ddd and the flags resulting from 
;;; the execution of each instruction was then added as a comment
;;; on the same line as the instruction.
;;; The flags are 
;;; CF: carry
;;; PF: parity (1 if the number of 1s in the result is even)
;;; AF: auxiliary carry (carry into the MSB)
;;; SF: sign (1 if result is negative, 0 otherwise)
;;; ZF: zero (1 if result is 0, 1 otherwise)
;;; IF: interrupt flag (used for critical sections)
;;; OF: overflow (1 if the result overflowed assuming signed numbers)
;;; ID: direction bit (for string operations)
;;; -------------------------------------------------------------------


EXIT    equ             1
        
      	;; ------------------------------------------------------------
	;; data areas
	;; ------------------------------------------------------------

	section	.data

        
	;; ------------------------------------------------------------
	;; code area
	;; ------------------------------------------------------------

	section	.text
	global	_start

_start: nop
        nop                     ; immediate   Flag values
                                ; value       AFTER the instruction
                                ;-----------  ----------------------
        mov     al, 0x43        ; 67
        cmp     al, 0x43        ;             PF ZF IF ID
        cmp     al, 0x42        ; 66                IF ID
        cmp     al, 0x44        ; 68          CF PF AF SF IF ID
        cmp     al, 0xff        ; 255 or -1   CF PF AF IF ID
        cmp     al, 0x81        ; 129 or -127 CF SF IF OF ID

        mov     al, 0xfe        ; 254, or -2 
        cmp     al, 0xff        ; 255  or -1  CF PF AF SF IF ID
        cmp     al, 0xfd        ; 253  or -3  IF ID
        cmp     al, 0x81        ; 129 or -127 PF IF ID
        cmp     al, 0x7f        ; 127         AF IF OF ID

	;; exit()

	mov	eax,EXIT
	mov	ebx,0
	int	0x80		; final system call


factorial.asm


;;; factorial.asm
;;;
;;; demo of the recursive factorial program
;;; uses the stack to pass parameters.
	
%include	"dumpRegs.asm"
	
	section	.data
n	dd	5		;n
factN	dd	0		;we'll put n! here

	section	.text
	global	_start

_start:	push	eax		;make room in stack for resut
	push	dword[n]	;pass n
	call	fact
	pop	eax		;put result in eax
	mov	dword[factN],eax ;and in global
	
	call	dumpRegs

;;; exit
	mov	eax, 1
	mov	ebx, 0
	int	0x80

;;; --------------------------------------------------------
;;; fact: computes the factorial of n, where n is passed in
;;; 	  eax.  Returns the result in edx
;;; --------------------------------------------------------
fact:	push	ebp
	mov	ebp, esp

	pushad

	mov	eax, [ebp+8]	;get n
	cmp	eax, 1
	jne	.recurse

	mov	dword[ebp+12], 1 ;set result to 1
	
	popad
	pop	ebx
	ret	1*4		;get rid of n param

.recurse:

	dec	eax
	push	eax		;make room for result
	push	eax		;pass n-1
	call	fact
	pop	eax		;get fact(n-1)
	mul	dword[ebp+8]	;mult by n
	mov	dword[ebp+12],eax
				;pass result back

	popad
	pop	ebp
	ret	1*4


fibonacci.asm


;;; fibonacci.asm
;;; D. Thiebaut
;;; simple program computing the first 5 fibonacci terms without
;;; using a loop.
;;; Each term is stored in a double word.
;;;

		section	.data
fib		dd	0, 0, 0, 0, 0

	
		section	.text
		global	_start
_start:
		mov	dword[fib], 1		 ; fib[0] <- 1
		mov	dword[fib+4], 1		 ; fib[1] <- 1
		mov	eax, dword[fib]		 ; eax <- fib[0]
	
		add	eax, dword[fib+4] 	 ; eax <- fib[0]+fib[1]
		mov	dword[fib+8], eax	 ; fib[2] <- eax

		add	eax, dword[fib+4]  	 ; eax <- fib[2] + fib[1]
		mov	dword[fib+12], eax 	 ; fib[3] <- eax

		add	eax, dword[fib+8] 	 ; eax <- fib[3] + fib[2] 
		mov	dword[fib+16], eax	 ; fib[4] <- eax

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


fibWithLoop2.asm


;;; fibWithLoop2.asm
;;; D. T.
;;; a simple demo program computing a few Fibonacci terms
;;; using indirect addressing modes and loops
;;; To compile and run
;;;   nasm -f elf fibWithLoop2.asm
;;;   nasm -f elf asm_io.asm
;;;   gcc -m32 -o fibWithLoop2 driver.c fibWithLoop2.o asm_io.o
;;;   ./fibWithLoop2
	
	     %include "asm_io.inc"

             ;; -------------------------
             ;; data segment
             ;; -------------------------
             section .data
Fib	     db     0,0,0,0,0,0

             ;; -------------------------
             ;; code area
             ;; -------------------------
             section .text
             global  asm_main
asm_main:       
	mov	ebx, 0			; make ebx point to array
	mov	ecx, 5			; # of terms to compute
	mov	eax, 1			; first term as double word (for printing)
	mov	byte [Fib+ebx], al	; set 1st term
	call	print_int		; print it
	call	print_nl
	
	mov	byte [Fib+ebx+1], al	; set 2nd term
	call	print_int		; print it
	call	print_nl
	
	sub	ecx,2			; adjust counter 
	add	ebx,2			; and pointer. ebx points to
					; empty Fib
	
for:	add	al, byte [Fib+ebx-2]	; al<- fib(n-1)+fib(n-2)
	mov	byte [Fib+ebx], al	; store new term
	call	print_int		; print it
	call	print_nl
	
	inc	ebx			; point to new term
        loop	for			; loop back

        ;; return to C program
	
        ret


fibWithLoop3.asm


;;; fibWithLoop2.asm
;;; D. T.
;;; a simple demo program computing a few Fibonacci terms
;;; using indirect addressing modes and loops
;;; To compile and run
;;;   nasm -f elf fibWithLoop2.asm
;;;   nasm -f elf asm_io.asm
;;;   gcc -m32 -o fibWithLoop2 driver.c fibWithLoop2.o asm_io.o
;;;   ./fibWithLoop2
	
	     %include "asm_io.inc"

             ;; -------------------------
             ;; data segment
             ;; -------------------------
             section .data
msg	     db     "How many terms do you want printed (1-20)? ", 0		
Fib	     times(20) db     0

             ;; -------------------------
             ;; code area
             ;; -------------------------
             section .text
             global  asm_main
asm_main:
	mov	eax, msg
	call	print_string
	call	read_int
	
	mov	ebx, 0			; make ebx point to array
	mov	ecx, eax		; # of terms to compute
	mov	eax, 1			; first term as double word (for printing)
	mov	byte [Fib+ebx], al	; set 1st term
	call	print_int		; print it
	call	print_nl
	
	mov	byte [Fib+ebx+1], al	; set 2nd term
	call	print_int		; print it
	call	print_nl
	
	sub	ecx,2			; adjust counter 
	add	ebx,2			; and pointer. ebx points to
					; empty Fib
	
for:	add	al, byte [Fib+ebx-2]	; al<- fib(n-1)+fib(n-2)
	mov	byte [Fib+ebx], al	; store new term
	call	print_int		; print it
	call	print_nl
	
	inc	ebx			; point to new term
        loop	for			; loop back

        ;; return to C program
	
        ret


fibWithLoop.asm


;;; fibWithLoop.asm
;;; D. T.
;;; a simple demo program computing a few Fibonacci terms
;;; using indirect addressing modes and loops

     %include "asm_io.inc"

             ;; -------------------------
             ;; data segment
             ;; -------------------------
             section .data
Fib	     db     0,0,0,0,0,0

             ;; -------------------------
             ;; code area
             ;; -------------------------
             section .text
             global  asm_main
asm_main:       
	mov	ebx, Fib	; make ebx point to array
	mov	ecx, 5		; # of terms to compute
	mov	eax, 1		; first term as double word (for printing)
	mov	byte[ebx], al	; set 1st term
	call	print_int	; print it
	call	print_nl
	
	mov	byte[ebx+1], al	; set 2nd term
	call	print_int	; print it
	call	print_nl
	
	sub	ecx,2		; adjust counter 
	add	ebx,2		; and pointer. ebx points to
				; empty Fib
	
for:	add	al, byte[ebx-2]	; al<- fib(n-1)+fib(n-2)
	mov	byte[ebx], al	; store new term
	call	print_int	; print it
	call	print_nl
	
	inc	ebx		; point to new term
        loop	for		; loop back

        ;; return to C program
	
        ret


float1.asm


; float1.asm   use "C" printf on float
; 
; Assemble:	nasm -f elf float1.asm
; Link:		gcc -m32 -o float1 float1.o
; Run:		./float1
; prints a single precision floating point number on the screen
; This program uses the external printf C  function which requires
; a format string defining what to print, and a variable number of
; variables to print.


        extern printf                   ; the C function to be called

        SECTION .data                   ; Data section

msg:    db      "flt1 = %e",0x0a,0x00
flt1:	dd	5.327e-30		; 32-bit floating point


	SECTION .bss
		
flttmp:	resq 1			        ; 64-bit temporary for printing flt1
	
        SECTION .text                   ; Code section.

        global	main		        ; "C" main program 
main:				        ; label, start of main program
	
	fld	dword [flt1]	        ; need to convert 32-bit to 64-bit
	fstp	qword [flttmp]          ; floating load makes 80-bit,
	                                ; store as 64-bit
		 
	push	dword [flttmp+4]        ; 32 bit floating point
	push	dword [flttmp]
        push    dword msg		; address of format string
        call    printf			; Call C function
        add     esp, 12			; pop stack 10*4 bytes

        mov     eax, 1			; exit code, 0=normal
	mov	ebx, 0
        int	0x80			;


funcExample2.asm


;;; ----------------------------------
;;; funcExample2.asm
;;; prints 2 strings with lines of stars
;;; between them
;;; ----------------------------------
		section	.data
Hello		db	"Hello "
There		db	"there!", 10, 10, 10
HelloLen	equ	$-Hello
line		db	"****************************", 10
lineLen		equ	$-line
	
		section	.text
		global	_start
_start:	
;;; ----------------------------------
;;; main program
;;; ----------------------------------
		call	printLine
	
		mov	ecx, Hello
		mov	edx, HelloLen
		call	printString
	
		call	printLine
	
		mov	ecx, There
		mov	edx, 9
		call	printString

		call 	printLine
	
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; ----------------------------------
;;; printString: Prints a string whose
;;; address is in ecx and length in edx
;;; ----------------------------------
printString:	mov	eax, 4
		mov	ebx, 1
;;; 		int 	0x80
;;; 		ret

;;; ----------------------------------
;;; printLine: prints a line of stars.
;;; ----------------------------------
printLine:	mov	ecx, line
		mov	edx, lineLen
		call	printString
		ret


funcExample3.asm


;;; ----------------------------------
;;; funcExample2.asm
;;; prints 2 strings with lines of stars
;;; between them
;;; ----------------------------------
%include "dumpRegs.inc"
	
		section	.data
a		dd	3
b		dd	2
res		dd	0
	
		section	.text
		global	_start
_start:	
;;; ----------------------------------
;;; main program
;;; ----------------------------------
		push	dword[a]
		push	dword[b]
		mov	eax, res
		push	eax

		call	sum

		mov	eax, dword[res]
		call	dumpRegs
	
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


sum:		push	ebp
		mov	ebp, esp
	
		push	eax
		push	ebx
	
		mov	eax, [ebp+12]
		add	eax, [ebp+16]
		mov	ebx, [ebp+8]
		mov	dword [ebx], eax

		pop	ebx
		pop	eax
	
		pop	ebp
		ret	3*4


funcExample.asm


;;; ------------------------------------
;;; funcExample.asm
;;; prints 2 strings using functions
;;; ------------------------------------

		section	.data
Hello		db	"Hello "
There		db	"there!", 10, 10, 10
HelloLen	equ	$-Hello

		section	.text
		global	_start
_start:	
;;; ------------------------------------
;;; main program
;;; ------------------------------------

;;; print message
		mov	ecx, Hello
		mov	edx, HelloLen
		call	printString

		mov	ecx, There
		mov	edx, 9
		call	printString
	
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; ------------------------------------
;;; printString: prints string whose
;;; address is in ecx, and length in edx
;;; ------------------------------------
printString:	
		mov	eax, 4
		mov	ebx, 1
		int 	0x80
		ret


hanoi1.asm


;;; hanoi1.asm
;;; D.T.
;;; Towers of Hanoi, top down...


;;; assumptions:
;;; al = n   		Number of disk
;;; bl = Source 	character identifying the source
;;; cl = Dest		character identifying the destination
;;; dl = Temp		character identifying the extra peg

		section	.data
moveStr		db	"X --> X", 10
moveStrLen	equ	$-moveStr
source		equ	moveStr + 0
dest		equ	moveStr	+ 6	

	section	.text
	global	_start
;;; ------------------------------------------------------------
;;; M A I N
;;; ------------------------------------------------------------

_start: 	mov	al, 4	; move 4 disks
		mov	bl, 'A'	; from A
		mov	cl, 'B'	; to B
		mov	dl, 'C'	; using C as extra
	
		call	moveDisks

;;; return to OS
		mov	eax, 1
		mov	ebx, 0
		int	0x80

;;; ------------------------------------------------------------
;;; moveDisks:
;;; assumptions:
;;; al = n   		Number of disk
;;; bl = Source 	character identifying the source
;;; cl = Dest		character identifying the destination
;;; dl = Temp		character identifying the extra peg
;;; Does not return anything
;;; does not modify registers
;;; ------------------------------------------------------------
moveDisks:	push	ax
		push	bx
		push	cx
		push	dx

		mov	byte[source], bl
		mov	byte[dest], cl
		call	printMove
	
		pop	dx
		pop	cx
		pop	bx
		pop	ax
		ret

;;; ------------------------------------------------------------
;;; printMove
;;; prints the string moveStr on the screen
;;; ------------------------------------------------------------
printMove:	pushad
		mov	eax, 4
		mov	ebx, 1
		mov	ecx, moveStr
		mov	edx, moveStrLen
		int	0x80
		popad
		ret


hanoi2.asm


;;; hanoi2.asm
;;; D.T.
;;; Towers of Hanoi, top down...


;;; assumptions:
;;; al = n   		Number of disk
;;; bl = Source 	character identifying the source
;;; cl = Dest		character identifying the destination
;;; dl = Temp		character identifying the extra peg

%define		N	4	; number of disks to move
	
		section	.data
moveStr		db	"X X", 10
moveStrLen	equ	$-moveStr
source		equ	moveStr + 0
dest		equ	moveStr	+ 2	

	section	.text
	global	_start
;;; ------------------------------------------------------------
;;; M A I N
;;; ------------------------------------------------------------

_start: 	mov	al,  N	; move 4 disks
		mov	bl, 'A'	; from A
		mov	cl, 'B'	; to B
		mov	dl, 'C'	; using C as extra
	
		call	moveDisks

;;; return to OS
		mov	eax, 1
		mov	ebx, 0
		int	0x80

;;; ------------------------------------------------------------
;;; moveDisks:
;;; assumptions:
;;; al = n   		Number of disk
;;; bl = Source 	character identifying the source
;;; cl = Dest		character identifying the destination
;;; dl = Temp		character identifying the extra peg
;;; Does not return anything
;;; does not modify registers
;;; ------------------------------------------------------------
moveDisks:	push	ax
		push	bx
		push	cx
		push	dx

		cmp	al, 1
		ja	.recurse
	
;;; only 1 to move: move from source to dest!
		mov	byte[source], bl
		mov	byte[dest], cl
		call	printMove
		jmp	.return

.recurse:
;;; move n-1 disk from source to temp
		dec	al	; al <-- n-1
		xchg	cl, dl	; swap dest and temp
		call	moveDisks
		xchg	cl, dl	; swap back dest and temp
	
;;; move 1 from source to dest
		push	ax
		mov	al, 1
		mov	byte[source], bl
		mov	byte[dest], cl
		call	printMove
		pop	ax
	
;;; move n-1 disk from temp to dest
		xchg	bl, dl	; make temp the source
		call	moveDisks
	
.return:	pop	dx
		pop	cx
		pop	bx
		pop	ax
		ret

;;; ------------------------------------------------------------
;;; printMove
;;; prints the string moveStr on the screen
;;; ------------------------------------------------------------
printMove:	pushad
		mov	eax, 4
		mov	ebx, 1
		mov	ecx, moveStr
		mov	edx, moveStrLen
   		int	0x80
		popad
		ret


hello2.asm


;;; skel.asm
;;; D. Thiebaut
;;;
;;; 
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs skel.asm
;;; 	ld -melf_i386 -o skel skel.o
;;; 	./skel
;;;

		section	.data
mesg1		db	"------------------------------------------------", 0x0a
mesg1Len	equ	$-mesg1
mesg2		db	"Hello!", 0x0a
mesg2Len	equ	$-mesg2	

	
		section	.text
		global	_start
_start:	


		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, mesg1
		mov	edx, mesg1Len
		int	0x80
	

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


hello3.asm


	section	.data

msg	db	"Hello", 0x0a, 0x0a
msgLen	equ	$-msg

	section	.text
	global	_start
_start:
	mov	eax,4
	mov	ebx,1
	mov	ecx,msg
	mov	edx,msgLen
	int	0x80

;;; exit
	mov	eax,1
	mov	ebx,0
	int	0x80


hello.asm


;;; helloWorld.asm
;;; D. Thiebaut
;;;
;;; Display "Hello there!" on the screen
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs helloWorld.asm
;;; 	ld -melf_i386 -o helloWorld helloWorld.o
;;; 	./helloWorld
;;;

		section	.data
Hello		db	"Hello there!", 10, 10, 10
HelloLen	equ	$-Hello

		section	.text
		global	_start
_start:	

;;; print message
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, Hello	; address of message to print
		mov	edx, HelloLen	; # of chars to print
		int 	0x80

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


helloMovsb.asm


;;; helloWorld.asm
;;; D. Thiebaut
;;;
;;; Display "Hello there!" on the screen
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs helloWorld.asm
;;; 	ld -melf_i386 -o helloWorld helloWorld.o
;;; 	./helloWorld
;;;

		section	.data
Hello		db	"Hello there!", 10, 10, 10
HelloLen	equ	$-Hello
NewHello	db	"            ", 0, 0, 0
	
		section	.text
		global	_start
_start:	

;;; print message
		mov	esi, Hello
		mov	edi, NewHello
		cld
		mov	ecx, HelloLen
	rep	movsb
	
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, NewHello	; address of message to print
		mov	edx, HelloLen	; # of chars to print
		int 	0x80

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


howMuchStack2.asm


;;; hwtest.asm
     ;;; a simple demo program to test I/O with
     ;;; a C "wrapper" program

     %include "asm_io.inc"

             ;; -------------------------
             ;; data segment
             ;; -------------------------
             section .data
     msg     db      "Hello! Please enter an integer number: ",0x00
     msg2    db      "You have entered ",0x00
     x       dd      0

             ;; -------------------------
             ;; code area
             ;; -------------------------
             section .text
             global  asm_main
     asm_main:       

	mov	ebx, esp
for:	mov	eax, esp
	sub	eax, ebx
	neg	eax
	call	print_int
	call	print_nl
	
	sub	esp, 100000	;equivalent to pushing 100,000 bytes
	
	jmp	for


        ret


howMuchStack.asm


;;; hwtest.asm
     ;;; a simple demo program to test I/O with
     ;;; a C "wrapper" program



             ;; -------------------------
             ;; data segment
             ;; -------------------------
             section .data

             ;; -------------------------
             ;; code area
             ;; -------------------------
             section .text
             global  _start
_start:	
	     jmp     _start

             ret


hw12_maze.asm


;;;__     ___     _ _   __  __
;;;\ \   / (_)___(_) |_|  \/  | __ _ _______
;;; \ \ / /| / __| | __| |\/| |/ _` |_  / _ \
;;;  \ V / | \__ \ | |_| |  | | (_| |/ /  __/
;;;   \_/  |_|___/_|\__|_|  |_|\__,_/___\___|
;;;
;;;
;;; Aurelia Moore (c) 2007
;;;
;;; This program takes a maze defined in maze1.dat where the
;;; walls are denoted by # and the empty space defined by
;;; spaces. The maze should be in the variable maze in
;;; maze1.dat, and the number of columns and rows in the maze
;;; in the variables width and height, respectively. It will
;;; then try to find a path through the maze. It will leave
;;; "breadcrumbs" for the path it is trying, and when it discovers
;;; that there are no successful paths from a point, places a v
;;; there.
;;;
;;; To assemble and run:
;;;     nasm -f elf -F stabs hw8.asm
;;;     gcc -o hw8 driver.c asm_io.o hw8.o
;;;     ./hw8
;;; -----------------------------------------------------------------------


;;;  ____        _          ____            _   _
;;; |  _ \  __ _| |_ __ _  / ___|  ___  ___| |_(_) ___  _ __
;;; | | | |/ _` | __/ _` | \___ \ / _ \/ __| __| |/ _ \| '_ \
;;; | |_| | (_| | || (_| |  ___) |  __/ (__| |_| | (_) | | | |
;;; |____/ \__,_|\__\__,_| |____/ \___|\___|\__|_|\___/|_| |_|
;;; 

        section .data

maze   db      "##########################"
width  equ     $-maze	
       db      "                         #"
       db      "#                        #"
       db      "                         #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "##########################"
height equ     ($-maze) / width	

WRITE   equ     4
STDOUT  equ     1

;;; clrScreen variables
home    db      27,"[2J"                ; clear the screen
        db      27,"[1;1H"              ; ansi sequence to bring
                                        ; cursor at position 1,1
homeLen equ     $-home

;;; My variables
i       dd      0                       ;Keeps track of which row we are on
j       dd      0                       ;Keeps track of which column we are on
fmsg    db      "Fail! No path found. I think this maze has no exit."
fmsgLen	equ	$-fmsg	
smsg    db      "Found a path!"
smsgLen	equ	$-smsg	


;;;   ____          _        ____            _   _
;;;  / ___|___   __| | ___  / ___|  ___  ___| |_(_) ___  _ __
;;; | |   / _ \ / _` |/ _ \ \___ \ / _ \/ __| __| |/ _ \| '_ \
;;; | |__| (_) | (_| |  __/  ___) |  __/ (__| |_| | (_) | | | |
;;;  \____\___/ \__,_|\___| |____/ \___|\___|\__|_|\___/|_| |_|
;;;         

        section .text
        global 	_start
_start:	
        ;;Push starting coordinates and call fn
        push    1                       ;Row 1
        push    0                       ;Column 0
        call    visitMaze
        jnc     none    ;if false, skip
	call 	printMaze
        call    printMazeSuccess
        jmp     done
none:
        call    printMazeFail
done:

        ;; return to O.S.
	mov	eax, 1
	mov	ebx, 0
	int	0x80

        
;;; -----------------------------------------------------------------------
        ;; visitMaze:
        ;;      Takes row then col on stack
        ;;      Checks if it is at an exit. Then checks to E,S,N,W,
        ;;      calling itself and checking for space. If it is @ an exit
        ;;      or recieves true from its recursion, it returns true.
        ;;      If none of its paths are viable (from walls, visited spaces,
        ;;      or paths that do not lead to an exit) it places a v and
        ;;      returns false.
;;; -----------------------------------------------------------------------

visitMaze:
        push    ebp                     ;Store old ebp
        mov     ebp,esp
        ;; Get row and col # from stack
        mov     eax,dword[ebp+12]
        mov     ebx,dword[ebp+8]
        call    ijoffset                ;eax<-offset
        mov     byte[maze+eax],"."      ;Change character to .
        mov     edx,eax                 ;copy offset
        call    printMaze               ;print, overwrites eax-ecx
        ;; Get back row and col #
        mov     eax,dword[ebp+12]       ;row #
        mov     ebx,dword[ebp+8]        ;col #
        mov     ecx,height              ;number of rows
        dec     ecx                     ;last row
        ;; Check for exit conidtions (!start and on 1st or last row or col)
        ;; exit row?
        cmp     eax,ecx                 ;in last row?
        je      exit
        cmp     eax,0                   ;in 1st row?
        je      exit
        ;; exit coulun?
        mov     ecx,width               ;# of Columns
        dec     ecx                     ;last columns
        cmp     ebx,ecx                 ;in last col?
        je      exit
        cmp     ebx,0                   ;in 1st col?
        jne     notExit                 ;If not, not at an exit
        cmp     eax,1                   ;If are in 1st col, check if entrance
        jne     exit                    ;if in 1st col but not row=1, exit
        jmp     notExit
exit:
        jmp     true                    ;If at exit, return true
notExit:

        ;; try east
east:
        mov     eax,dword[ebp+12]       ;get row
        mov     ebx,dword[ebp+8]        ;get col
        inc     ebx                     ;column+1
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to East
        cmp     al," "                  ;is it blank
        jne     south                   ;if no go to next direction
        ;; Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        push    eax                     ;row
        push    ebx                     ;col
        call    visitMaze
        jnc     south                   ;if visitMaze returns false
        jmp     true                    ;if returns true,return true
        ;; try south
south:
        mov     eax,dword[ebp+12]       ;get row
        inc     eax                     ;row+1
        mov     ebx,dword[ebp+8]        ;get col
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to South
        cmp     al," "                  ;Is it blank
        jne     north
        ;; Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        inc     eax                     ;row+1
        push    eax
        push    ebx                     ;column
        call    visitMaze
        jc      true                    ;if visitMaze returned true

north:
        mov     eax,dword[ebp+12]       ;get row
        dec     eax                     ;row-1
        mov     ebx,dword[ebp+8]        ;get col
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to North
        cmp     al," "                  ;Is it blank
        jne     west
        ;;  Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        dec     eax                     ;row-1
        push    eax
        push    ebx                     ;column
        call    visitMaze
        jc      true                    ;if visitMaze returned true
west:
        mov     eax,dword[ebp+12]       ;get row
        mov     ebx,dword[ebp+8]        ;get col
        dec     ebx                     ;col-1
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to east
        cmp     al," "                  ;Is it blank
        jne     false
        ;;  Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        push    eax
        push    ebx                     ;column
        call    visitMaze
        jc      true                    ;if visitMaze returned true
false:
        ;;change to v and print
        mov     eax,dword[ebp+12]
        mov     ebx,dword[ebp+8]
        call    ijoffset                ;eax<-offset
        lea     eax, [maze+eax]
        mov     byte[eax],'v'
        call    printMaze
        ;;return 0
        clc                             ;set carry bit = 0 (return false)
        pop     ebp
        ret     8

true:
        stc                             ;set carry = 1 (return true)
        pop     ebp
        ret     8

        
;;; -----------------------------------------------------------------------
        ;; printMaze: prints the maze in the maze variable
        ;; Nothing needs to be passed
;;; -----------------------------------------------------------------------
printMaze:
        call    killTime
        call    clrScreen
initfori1:
        mov     dword[i],0              ;Start at 1st row
        mov     ecx,height              ;Loop once for each row
fori1:  push    ecx                     ;Store loop counter
intiforj1:
        mov     dword[j],0              ;1st column
        mov     ecx,width               ;Loop once for each column
forj1:
        push    ecx
        ;; Get ready to call offset fn
        mov     eax, [i]
        mov     ebx, [j]
        call    ijoffset
        mov     al, byte[maze+eax]      ;Get correct character in maze
        call    print_char
        inc     dword[j]                ;go to next column
        pop     ecx                     ;Retrieve loop counter
        loop    forj1

        call    print_nl
        pop     ecx
        inc     dword[i]                ;next row
        loop    fori1
        ret

;;; -----------------------------------------------------------------------
;;; -----------------------------------------------------------------------
	section	.data
char	db	'.'	
	section	.text
print_char:
	pushad
	mov	byte[char], al
	mov	eax, 4
	mov	ebx, 1
	mov	ecx, char
	mov	edx, 1
	int	0x80
	popad
	ret

;;; -----------------------------------------------------------------------
;;; -----------------------------------------------------------------------
print_string:
	pushad
	mov	ecx, eax
	mov	eax, 4
	mov	ebx, 1
	int	0x80
	popad
	ret
	
;;; -----------------------------------------------------------------------
;;; -----------------------------------------------------------------------
print_nl:
	push	ax
	mov	al, 0x0a
	call	print_char
	pop	ax
	ret
	
;;; -----------------------------------------------------------------------
        ;;      printMazeSuccess: same as printMaze, but replaces v's with
        ;;      spaces and says a path was found
;;; -----------------------------------------------------------------------
printMazeSuccess:
        call    print_nl

        mov     eax,smsg
	push	edx
	mov	edx,smsgLen
        call    print_string
	pop	edx
        call    print_nl
        ret

        
;;; -----------------------------------------------------------------------
        ;;      printMazeFail: same as printMaze, but replaces anything
        ;;      that is not a # with a space,and says no path was found
;;; -----------------------------------------------------------------------
        
printMazeFail:
	call	print_nl
	
        mov     eax,fmsg
	push	edx
	mov	edx, fmsgLen
        call    print_string
	pop	edx
        call    print_nl
        ret

        
;;; -----------------------------------------------------------------------
        ;;  ijoffset: gets a coordinate in the maze, taking the row # from eax
        ;;               and the column # from ebx, and calculates the
        ;;               appropriate offset and stores it in eax.
        ;;       uses eax, ebx, ecx
;;; -----------------------------------------------------------------------

ijoffset:
        mov     ecx, width              ;Number of columns
        mul     ecx                     ;eax<-row # * number of columns
        add     eax,ebx                 ;eax<-row# * # of columns + column #
        ret

;;; -----------------------------------------------------------------------
        ;; ------------------------------------------------------
        ;; clrScreen:  clears the screen and brings the cursor
        ;; to "home" position.  This is done by using ANSI sequences
        ;; that, when sent to the screen, do not actually print
        ;; anything, but instead modify different things, such as
        ;; the position of the cursor, the contents of the screen,
        ;; or other screen-related properties.  All ansi sequences
        ;; start with Ascii 27, which is the ESCape character.
;;; -----------------------------------------------------------------------
        
clrScreen:
        pushad                          ; save all registers

        mov             eax,WRITE       ; already defined
        mov             ebx,STDOUT      ; already defined
        lea             ecx,[home]
        mov             edx,homeLen
        int             0x80

        popad                           ; restore all registers
        ret

;;; -----------------------------------------------------------------------
        ;; killTime: performs many additions and subtractions between
        ;; each visit to make it easier to see each step of the
        ;; visiting process.
;;; -----------------------------------------------------------------------

killTime:
        pushad                          ;push all 32-bit registers
        mov     ecx, 50000000
for:    mov     edx, 1
        add     edx, 1
        sub     edx, 1
        loop    for
        popad                           ;pop all 32-bit registers
        ret


hw12_play.asm


;;;__     ___     _ _   __  __
;;;\ \   / (_)___(_) |_|  \/  | __ _ _______
;;; \ \ / /| / __| | __| |\/| |/ _` |_  / _ \
;;;  \ V / | \__ \ | |_| |  | | (_| |/ /  __/
;;;   \_/  |_|___/_|\__|_|  |_|\__,_/___\___|
;;;
;;;
;;; Aurelia Moore (c) 2007
;;;
;;; This program takes a maze defined in maze1.dat where the
;;; walls are denoted by # and the empty space defined by
;;; spaces. The maze should be in the variable maze in
;;; maze1.dat, and the number of columns and rows in the maze
;;; in the variables width and height, respectively. It will
;;; then try to find a path through the maze. It will leave
;;; "breadcrumbs" for the path it is trying, and when it discovers
;;; that there are no successful paths from a point, places a v
;;; there.
;;;
;;; To assemble and run:
;;;     nasm -f elf -F stabs hw8.asm
;;;     gcc -o hw8 driver.c asm_io.o hw8.o
;;;     ./hw8
;;; -----------------------------------------------------------------------


;;;  ____        _          ____            _   _
;;; |  _ \  __ _| |_ __ _  / ___|  ___  ___| |_(_) ___  _ __
;;; | | | |/ _` | __/ _` | \___ \ / _ \/ __| __| |/ _ \| '_ \
;;; | |_| | (_| | || (_| |  ___) |  __/ (__| |_| | (_) | | | |
;;; |____/ \__,_|\__\__,_| |____/ \___|\___|\__|_|\___/|_| |_|
;;; 

        section .data

maze   db      "##########################"
width  equ     $-maze	
       db      "                         #"
       db      "#                        #"
       db      "                         #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "#                        #"
       db      "##########################"
height equ     ($-maze) / width	

WRITE   equ     4
STDOUT  equ     1

;;; clrScreen variables
home    db      27,"[2J"                ; clear the screen
        db      27,"[1;1H"              ; ansi sequence to bring
                                        ; cursor at position 1,1
homeLen equ     $-home

;;; My variables
i       dd      0                       ;Keeps track of which row we are on
j       dd      0                       ;Keeps track of which column we are on
fmsg    db      "Fail! No path found. I think this maze has no exit."
fmsgLen	equ	$-fmsg	
smsg    db      "Found a path!"
smsgLen	equ	$-smsg	
firstesp dd	0

;;;   ____          _        ____            _   _
;;;  / ___|___   __| | ___  / ___|  ___  ___| |_(_) ___  _ __
;;; | |   / _ \ / _` |/ _ \ \___ \ / _ \/ __| __| |/ _ \| '_ \
;;; | |__| (_) | (_| |  __/  ___) |  __/ (__| |_| | (_) | | | |
;;;  \____\___/ \__,_|\___| |____/ \___|\___|\__|_|\___/|_| |_|
;;;         

        section .text
        global 	_start
_start:
	mov	[firstesp],esp
	
        ;;Push starting coordinates and call fn
        push    1                       ;Row 1
        push    0                       ;Column 0
        call    visitMaze
        jnc     none    ;if false, skip
	call 	printMaze
        call    printMazeSuccess
        jmp     done
none:
        call    printMazeFail
done:

        ;; return to O.S.
	mov	eax, 1
	mov	ebx, 0
	int	0x80

        
;;; -----------------------------------------------------------------------
        ;; visitMaze:
        ;;      Takes row then col on stack
        ;;      Checks if it is at an exit. Then checks to E,S,N,W,
        ;;      calling itself and checking for space. If it is @ an exit
        ;;      or recieves true from its recursion, it returns true.
        ;;      If none of its paths are viable (from walls, visited spaces,
        ;;      or paths that do not lead to an exit) it places a v and
        ;;      returns false.
;;; -----------------------------------------------------------------------

visitMaze:
        push    ebp                     ;Store old ebp
        mov     ebp,esp

	push	eax
	mov	eax, esp
	sub	eax, [firstesp]
	neg	eax
	call	printReg
	
	pop	eax
	
        ;; Get row and col # from stack
        mov     eax,dword[ebp+12]
        mov     ebx,dword[ebp+8]
        call    ijoffset                ;eax<-offset
        mov     byte[maze+eax],"."      ;Change character to .
        mov     edx,eax                 ;copy offset
        call    printMaze               ;print, overwrites eax-ecx
        ;; Get back row and col #
        mov     eax,dword[ebp+12]       ;row #
        mov     ebx,dword[ebp+8]        ;col #
        mov     ecx,height              ;number of rows
        dec     ecx                     ;last row
        ;; Check for exit conidtions (!start and on 1st or last row or col)
        ;; exit row?
        cmp     eax,ecx                 ;in last row?
        je      exit
        cmp     eax,0                   ;in 1st row?
        je      exit
        ;; exit coulun?
        mov     ecx,width               ;# of Columns
        dec     ecx                     ;last columns
        cmp     ebx,ecx                 ;in last col?
        je      exit
        cmp     ebx,0                   ;in 1st col?
        jne     notExit                 ;If not, not at an exit
        cmp     eax,1                   ;If are in 1st col, check if entrance
        jne     exit                    ;if in 1st col but not row=1, exit
        jmp     notExit
exit:
        jmp     true                    ;If at exit, return true
notExit:

        ;; try east
east:
        mov     eax,dword[ebp+12]       ;get row
        mov     ebx,dword[ebp+8]        ;get col
        inc     ebx                     ;column+1
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to East
        cmp     al," "                  ;is it blank
        jne     south                   ;if no go to next direction
        ;; Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        push    eax                     ;row
        push    ebx                     ;col
        call    visitMaze
        jnc     south                   ;if visitMaze returns false
        jmp     true                    ;if returns true,return true
        ;; try south
south:
        mov     eax,dword[ebp+12]       ;get row
        inc     eax                     ;row+1
        mov     ebx,dword[ebp+8]        ;get col
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to South
        cmp     al," "                  ;Is it blank
        jne     north
        ;; Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        inc     eax                     ;row+1
        push    eax
        push    ebx                     ;column
        call    visitMaze
        jc      true                    ;if visitMaze returned true

north:
        mov     eax,dword[ebp+12]       ;get row
        dec     eax                     ;row-1
        mov     ebx,dword[ebp+8]        ;get col
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to North
        cmp     al," "                  ;Is it blank
        jne     west
        ;;  Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        dec     eax                     ;row-1
        push    eax
        push    ebx                     ;column
        call    visitMaze
        jc      true                    ;if visitMaze returned true
west:
        mov     eax,dword[ebp+12]       ;get row
        mov     ebx,dword[ebp+8]        ;get col
        dec     ebx                     ;col-1
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to east
        cmp     al," "                  ;Is it blank
        jne     false
        ;;  Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        push    eax
        push    ebx                     ;column
        call    visitMaze
        jc      true                    ;if visitMaze returned true
false:
        ;;change to v and print
        mov     eax,dword[ebp+12]
        mov     ebx,dword[ebp+8]
        call    ijoffset                ;eax<-offset
        lea     eax, [maze+eax]
        mov     byte[eax],'v'
        call    printMaze
        ;;return 0
        clc                             ;set carry bit = 0 (return false)
        pop     ebp
        ret     8

true:
        stc                             ;set carry = 1 (return true)
        pop     ebp
        ret     8

        
;;; -----------------------------------------------------------------------
        ;; printMaze: prints the maze in the maze variable
        ;; Nothing needs to be passed
;;; -----------------------------------------------------------------------
printMaze:
        call    killTime
        call    clrScreen
initfori1:
        mov     dword[i],0              ;Start at 1st row
        mov     ecx,height              ;Loop once for each row
fori1:  push    ecx                     ;Store loop counter
intiforj1:
        mov     dword[j],0              ;1st column
        mov     ecx,width               ;Loop once for each column
forj1:
        push    ecx
        ;; Get ready to call offset fn
        mov     eax, [i]
        mov     ebx, [j]
        call    ijoffset
        mov     al, byte[maze+eax]      ;Get correct character in maze
        call    print_char
        inc     dword[j]                ;go to next column
        pop     ecx                     ;Retrieve loop counter
        loop    forj1

        call    print_nl
        pop     ecx
        inc     dword[i]                ;next row
        loop    fori1
        ret

;;; -----------------------------------------------------------------------
;;; -----------------------------------------------------------------------
	section	.data
char	db	'.'	
	section	.text
print_char:
	pushad
	mov	byte[char], al
	mov	eax, 4
	mov	ebx, 1
	mov	ecx, char
	mov	edx, 1
	int	0x80
	popad
	ret

;;; -----------------------------------------------------------------------
;;; -----------------------------------------------------------------------
print_string:
	pushad
	mov	ecx, eax
	mov	eax, 4
	mov	ebx, 1
	int	0x80
	popad
	ret
	
;;; -----------------------------------------------------------------------
;;; -----------------------------------------------------------------------
print_nl:
	push	ax
	mov	al, 0x0a
	call	print_char
	pop	ax
	ret
	
;;; -----------------------------------------------------------------------
        ;;      printMazeSuccess: same as printMaze, but replaces v's with
        ;;      spaces and says a path was found
;;; -----------------------------------------------------------------------
printMazeSuccess:
        call    print_nl

        mov     eax,smsg
	push	edx
	mov	edx,smsgLen
        call    print_string
	pop	edx
        call    print_nl
        ret

        
;;; -----------------------------------------------------------------------
        ;;      printMazeFail: same as printMaze, but replaces anything
        ;;      that is not a # with a space,and says no path was found
;;; -----------------------------------------------------------------------
        
printMazeFail:
	call	print_nl
	
        mov     eax,fmsg
	push	edx
	mov	edx, fmsgLen
        call    print_string
	pop	edx
        call    print_nl
        ret

        
;;; -----------------------------------------------------------------------
        ;;  ijoffset: gets a coordinate in the maze, taking the row # from eax
        ;;               and the column # from ebx, and calculates the
        ;;               appropriate offset and stores it in eax.
        ;;       uses eax, ebx, ecx
;;; -----------------------------------------------------------------------

ijoffset:
        mov     ecx, width              ;Number of columns
        mul     ecx                     ;eax<-row # * number of columns
        add     eax,ebx                 ;eax<-row# * # of columns + column #
        ret

;;; -----------------------------------------------------------------------
        ;; ------------------------------------------------------
        ;; clrScreen:  clears the screen and brings the cursor
        ;; to "home" position.  This is done by using ANSI sequences
        ;; that, when sent to the screen, do not actually print
        ;; anything, but instead modify different things, such as
        ;; the position of the cursor, the contents of the screen,
        ;; or other screen-related properties.  All ansi sequences
        ;; start with Ascii 27, which is the ESCape character.
;;; -----------------------------------------------------------------------
        
clrScreen:
        pushad                          ; save all registers

        mov             eax,WRITE       ; already defined
        mov             ebx,STDOUT      ; already defined
        lea             ecx,[home]
        mov             edx,homeLen
        int             0x80

        popad                           ; restore all registers
        ret

;;; -----------------------------------------------------------------------
        ;; killTime: performs many additions and subtractions between
        ;; each visit to make it easier to see each step of the
        ;; visiting process.
;;; -----------------------------------------------------------------------

killTime:
        pushad                          ;push all 32-bit registers
        mov     ecx, 50000000
for:    mov     edx, 1
        add     edx, 1
        sub     edx, 1
        loop    for
        popad                           ;pop all 32-bit registers
        ret


hw12_sol.asm


;;;__     ___     _ _   __  __
;;;\ \   / (_)___(_) |_|  \/  | __ _ _______
;;; \ \ / /| / __| | __| |\/| |/ _` |_  / _ \
;;;  \ V / | \__ \ | |_| |  | | (_| |/ /  __/
;;;   \_/  |_|___/_|\__|_|  |_|\__,_/___\___|
;;;
;;;
;;; Aurelia Moore, 2007
;;;
;;; This program takes a maze defined in maze1.dat where the
;;; walls are denoted by # and the empty space defined by
;;; spaces. The maze should be in the variable maze in
;;; maze1.dat, and the number of columns and rows in the maze
;;; in the variables width and height, respectively. It will
;;; then try to find a path through the maze. It will leave
;;; "breadcrumbs" for the path it is trying, and when it discovers
;;; that there are no successful paths from a point, places a v
;;; there. The program will end 2 ways: it finds an exit, or returns
;;; to the entrance to put a v there. If it found an exit, it
;;; removes all v's from to show only the maze and the
;;; breadcrumbs for the succesful path, and notes it has found a
;;; path. If it does not, it prints the maze without v's or
;;; breadcrumbs, and notes that it has failed.
;;;
;;; Each visitMaze puts a net 4 doublewords (16 bytes) on the stack:
;;; the row, column, return address, and stored ebp. During the
;;; execution of visitMaze, up to 40 bytes are added, but they
;;; are removed before the next visitMaze is called. They are the
;;; return address when printMaze is called, the return address
;;; when printMaze calls killTime, and the 8 registers that are
;;; pushed during killTime.
;;;
;;; If there are the 10,485,760 bytes I calculated in hw7 for the
;;; stack, then the 40 bytes that only occur once (they don't
;;; "stack") can be taken off the maximum available for the
;;; recursions. If visitMaze is called and there isn't this amount
;;; available in the stack, it will not succeed in running. So
;;; there are 10,485,720 bytes available for recursions. If there
;;; are 16 bytes used in each recursion, there are 655,357 possible
;;; recursions. This is the number in "open" paths, so not including
;;; bits we've marked with v.
;;; In the worst case scenario, where it visits every space in the
;;; interior of a blank maze and then goes to an exit, it will have
;;; (# of rows - 2) * (# of columns - 2) + 2 recursions. The - 2 to
;;; the rows and columns are for the walls - if they are not there
;;; it will exit. The +2 is for the entrance and exit.
;;; In the best case scenario for no walls, where it goes straight to
;;; the exit, it will have the # of columns recursions (it will go to
;;; the opposit wall in the last column).
;;; In the best case scenario for any maze with interior walls, there
;;; is a wall immediatly east of the entrance, and visitMaze is called
;;; only once.
;;;
;;; To assemble and run:
;;;     nasm -f elf -F stabs hw8.asm
;;;     gcc -o hw8 driver.c asm_io.o hw8.o
;;;     ./hw8
;;; -----------------------------------------------------------------------


;;;  ____        _          ____            _   _
;;; |  _ \  __ _| |_ __ _  / ___|  ___  ___| |_(_) ___  _ __
;;; | | | |/ _` | __/ _` | \___ \ / _ \/ __| __| |/ _ \| '_ \
;;; | |_| | (_| | || (_| |  ___) |  __/ (__| |_| | (_) | | | |
;;; |____/ \__,_|\__\__,_| |____/ \___|\___|\__|_|\___/|_| |_|
;;; 

        section .data
%include "maze1.dat"
WRITE   equ     4
STDOUT  equ     1

;;; clrScreen variables
home    db      27,"[2J"                ; clear the screen
        db      27,"[1;1H"              ; ansi sequence to bring
                                        ; cursor at position 1,1
homeLen equ     $-home

;;; My variables
i       dd      0                       ;Keeps track of which row we are on
j       dd      0                       ;Keeps track of which column we are on
fmsg    db      "Fail! No path found. I think this maze has no exit."
fmsgLen	equ	$-fmsg	
smsg    db      "Found a path!"
smsgLen	equ	$-smsg	


;;;   ____          _        ____            _   _
;;;  / ___|___   __| | ___  / ___|  ___  ___| |_(_) ___  _ __
;;; | |   / _ \ / _` |/ _ \ \___ \ / _ \/ __| __| |/ _ \| '_ \
;;; | |__| (_) | (_| |  __/  ___) |  __/ (__| |_| | (_) | | | |
;;;  \____\___/ \__,_|\___| |____/ \___|\___|\__|_|\___/|_| |_|
;;;         

        section .text
        global 	_start
_start:	
        ;;Push starting coordinates and call fn
        push    1                       ;Row 1
        push    0                       ;Column 0
        call    visitMaze
        jnc     none    ;if false, skip
        call    printMazeSuc
        jmp     done
none:
        call    printMazeFail
done:

        ;; return to O.S.
	mov	eax, 1
	mov	ebx, 0
	int	0x80

        
;;; -----------------------------------------------------------------------
        ;; visitMaze:
        ;;      Takes row then col on stack
        ;;      Checks if it is at an exit. Then checks to E,S,N,W,
        ;;      calling itself and checking for space. If it is @ an exit
        ;;      or recieves true from its recursion, it returns true.
        ;;      If none of its paths are viable (from walls, visited spaces,
        ;;      or paths that do not lead to an exit) it places a v and
        ;;      returns false.
;;; -----------------------------------------------------------------------

visitMaze:
        push    ebp                     ;Store old ebp
        mov     ebp,esp
        ;; Get row and col # from stack
        mov     eax,dword[ebp+12]
        mov     ebx,dword[ebp+8]
        call    ijoffset                ;eax<-offset
        mov     byte[maze+eax],"."      ;Change character to .
        mov     edx,eax                 ;copy offset
        call    printMaze               ;print, overwrites eax-ecx
        ;; Get back row and col #
        mov     eax,dword[ebp+12]       ;row #
        mov     ebx,dword[ebp+8]        ;col #
        mov     ecx,height              ;number of rows
        dec     ecx                     ;last row
        ;; Check for exit conidtions (!start and on 1st or last row or col)
        ;; exit row?
        cmp     eax,ecx                 ;in last row?
        je      exit
        cmp     eax,0                   ;in 1st row?
        je      exit
        ;; exit coulun?
        mov     ecx,width               ;# of Columns
        dec     ecx                     ;last columns
        cmp     ebx,ecx                 ;in last col?
        je      exit
        cmp     ebx,0                   ;in 1st col?
        jne     notExit                 ;If not, not at an exit
        cmp     eax,1                   ;If are in 1st col, check if entrance
        jne     exit                    ;if in 1st col but not row=1, exit
        jmp     notExit
exit:
        jmp     true                    ;If at exit, return true
notExit:

        ;; try east
east:
        mov     eax,dword[ebp+12]       ;get row
        mov     ebx,dword[ebp+8]        ;get col
        inc     ebx                     ;column+1
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to East
        cmp     al," "                  ;is it blank
        jne     south                   ;if no go to next direction
        ;; Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        push    eax                     ;row
        push    ebx                     ;col
        call    visitMaze
        jnc     south                   ;if visitMaze returns false
        jmp     true                    ;if returns true,return true
        ;; try south
south:
        mov     eax,dword[ebp+12]       ;get row
        inc     eax                     ;row+1
        mov     ebx,dword[ebp+8]        ;get col
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to South
        cmp     al," "                  ;Is it blank
        jne     north
        ;; Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        inc     eax                     ;row+1
        push    eax
        push    ebx                     ;column
        call    visitMaze
        jc      true                    ;if visitMaze returned true

north:
        mov     eax,dword[ebp+12]       ;get row
        dec     eax                     ;row-1
        mov     ebx,dword[ebp+8]        ;get col
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to North
        cmp     al," "                  ;Is it blank
        jne     west
        ;;  Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        dec     eax                     ;row-1
        push    eax
        push    ebx                     ;column
        call    visitMaze
        jc      true                    ;if visitMaze returned true
west:
        mov     eax,dword[ebp+12]       ;get row
        mov     ebx,dword[ebp+8]        ;get col
        dec     ebx                     ;col-1
        call    ijoffset                ;eax<-offset
        mov     al,byte[maze+eax]       ;get char to east
        cmp     al," "                  ;Is it blank
        jne     false
        ;;  Prepare to call/recurse
        mov     eax,dword[ebp+12]       ;row
        push    eax
        push    ebx                     ;column
        call    visitMaze
        jc      true                    ;if visitMaze returned true
false:
        ;;change to v and print
        mov     eax,dword[ebp+12]
        mov     ebx,dword[ebp+8]
        call    ijoffset                ;eax<-offset
        lea     eax, [maze+eax]
        mov     byte[eax],'v'
        call    printMaze
        ;;return 0
        clc                             ;set carry bit = 0 (return false)
        pop     ebp
        ret     8

true:
        stc                             ;set carry = 1 (return true)
        pop     ebp
        ret     8

        
;;; -----------------------------------------------------------------------
        ;; printMaze: prints the maze in the maze variable
        ;; Nothing needs to be passed
;;; -----------------------------------------------------------------------
printMaze:
        call    killTime
        call    clrScreen
initfori1:
        mov     dword[i],0              ;Start at 1st row
        mov     ecx,height              ;Loop once for each row
fori1:  push    ecx                     ;Store loop counter
intiforj1:
        mov     dword[j],0              ;1st column
        mov     ecx,width               ;Loop once for each column
forj1:
        push    ecx
        ;; Get ready to call offset fn
        mov     eax, [i]
        mov     ebx, [j]
        call    ijoffset
        mov     al, byte[maze+eax]      ;Get correct character in maze
        call    print_char
        inc     dword[j]                ;go to next column
        pop     ecx                     ;Retrieve loop counter
        loop    forj1

        call    print_nl
        pop     ecx
        inc     dword[i]                ;next row
        loop    fori1
        ret

;;; -----------------------------------------------------------------------
;;; -----------------------------------------------------------------------
	section	.data
char	db	'.'	
	section	.text
print_char:
	pushad
	mov	byte[char], al
	mov	eax, 4
	mov	ebx, 1
	mov	ecx, char
	mov	edx, 1
	int	0x80
	popad
	ret

;;; -----------------------------------------------------------------------
;;; -----------------------------------------------------------------------
print_string:
	pushad
	mov	ecx, eax
	mov	eax, 4
	mov	ebx, 1
	int	0x80
	popad
	ret
	
;;; -----------------------------------------------------------------------
;;; -----------------------------------------------------------------------
print_nl:
	push	ax
	mov	al, 0x0a
	call	print_char
	pop	ax
	ret
	
;;; -----------------------------------------------------------------------
        ;;      printMazeSuc: same as printMaze, but replaces v's with
        ;;      spaces and says a path was found
;;; -----------------------------------------------------------------------
printMazeSuc:
        call    killTime
        call    clrScreen
initfori2:
        mov     dword[i],0              ;Start at 1st row
        mov     ecx,height              ;Loop once for each row
fori2:  push    ecx                     ;Store loop counter
intiforj2:
        mov     dword[j],0              ;1st column
        mov     ecx,width               ;Loop once for each column
forj2:
        push    ecx
        ;; Get ready to call offset fn
        mov     eax, [i]
        mov     ebx, [j]
        call    ijoffset
        mov     al, byte[maze+eax]      ;Get correct character in maze
        ;;If character is v, replace with space
        cmp     al,'v'
        jne     print1
        mov     al,' '
print1:
        call    print_char
        inc     dword[j]                ;go to next column
        pop     ecx                     ;Retrieve loop counter
        loop    forj2

        call    print_nl
        pop     ecx
        inc     dword[i]                ;next row
        loop    fori2
        mov     eax,smsg
	push	edx
	mov	edx,smsgLen
        call    print_string
	pop	edx
        call    print_nl
        ret

        
;;; -----------------------------------------------------------------------
        ;;      printMazeFail: same as printMaze, but replaces anything
        ;;      that is not a # with a space,and says no path was found
;;; -----------------------------------------------------------------------
        
printMazeFail:
        call    killTime
        call    clrScreen
initfori3:
        mov     dword[i],0              ;Start at 1st row
        mov     ecx,height              ;Loop once for each row
fori3:  push    ecx                     ;Store loop counter
intiforj3:
        mov     dword[j],0              ;1st column
        mov     ecx,width               ;Loop once for each column
forj3:
        push    ecx
        ;; Get ready to call offset fn
        mov     eax, [i]
        mov     ebx, [j]
        call    ijoffset
        mov     al, byte[maze+eax]      ;Get correct character in maze
        ;;If character is not #, replace with space
        cmp     al,'#'
        je      print2
        mov al,' '
print2:
        call    print_char
        inc     dword[j]                ;Go to next column
        pop     ecx                     ;Retrieve loop counter
        loop    forj3

        call    print_nl
        pop     ecx
        inc     dword[i]                ;next row
        loop    fori3
        mov     eax,fmsg
	push	edx
	mov	edx, fmsgLen
        call    print_string
	pop	edx
        call    print_nl
        ret

        
;;; -----------------------------------------------------------------------
        ;;  ijoffset: gets a coordinate in the maze, taking the row # from eax
        ;;               and the column # from ebx, and calculates the
        ;;               appropriate offset and stores it in eax.
        ;;       uses eax, ebx, ecx
;;; -----------------------------------------------------------------------

ijoffset:
        mov     ecx, width              ;Number of columns
        mul     ecx                     ;eax<-row # * number of columns
        add     eax,ebx                 ;eax<-row# * # of columns + column #
        ret

;;; -----------------------------------------------------------------------
        ;; ------------------------------------------------------
        ;; clrScreen:  clears the screen and brings the cursor
        ;; to "home" position.  This is done by using ANSI sequences
        ;; that, when sent to the screen, do not actually print
        ;; anything, but instead modify different things, such as
        ;; the position of the cursor, the contents of the screen,
        ;; or other screen-related properties.  All ansi sequences
        ;; start with Ascii 27, which is the ESCape character.
;;; -----------------------------------------------------------------------
        
clrScreen:
        pushad                          ; save all registers

        mov             eax,WRITE       ; already defined
        mov             ebx,STDOUT      ; already defined
        lea             ecx,[home]
        mov             edx,homeLen
        int             0x80

        popad                           ; restore all registers
        ret

;;; -----------------------------------------------------------------------
        ;; killTime: performs many additions and subtractions between
        ;; each visit to make it easier to see each step of the
        ;; visiting process.
;;; -----------------------------------------------------------------------

killTime:
        pushad                          ;push all 32-bit registers
        mov     ecx, 50000000
for:    mov     edx, 1
        add     edx, 1
        sub     edx, 1
        loop    for
        popad                           ;pop all 32-bit registers
        ret


hw3b.asm


		section	.data
msg1        db             "CSC231 Assembly", 10, 10
msg1Len   equ            $-msg1
msg2        db             "................", 10
msg2Len   equ            $-msg2
msg3        db             "Fall 2012", 10, 10
msg3Len   equ            $-msg3

	
		section	.text
		global	_start
_start:	
;;; print msg1
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, msg1	; address of message to print
		mov	edx, msg1Len	; # of chars to print
		int 	0x80

;;; print msg2
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, msg2	; address of message to print
		mov	edx, msg2Len	; # of chars to print
		int 	0x80

;;; print msg3
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, msg3	; address of message to print
		mov	edx, msg3Len	; # of chars to print
		int 	0x80

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


hw3c.asm


;;; hw3c.asm
;;;
;;; 
;;;
;;;

		section	.data
msg1		db	"I love chocolate", 10
msg1Len		equ	$-msg1	

	
		section	.text
		global	_start
_start:	

;;; print original string
	        mov	eax, 4
		mov	ebx, 1
		mov	ecx, msg1
		mov	edx, msg1Len
		int	0x80
;;; put your code here

;;; print modified string
	        mov	eax, 4
		mov	ebx, 1
		mov	ecx, msg1
		mov	edx, msg1Len
		int	0x80
	
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


hw8asol2.asm


;;; ---------------------------------------------------------
;;; hw8aSol2.asm
;;; D. Thiebaut
;;; 11/13/12
;;; This program uses the library dumpRegs.asm to dump 
;;; the contents of the main 6 registers (eax, ebx, ecx,
;;; edx, esi and edi) to the screen.  Great for debugging without
;;; a debugger.
;;;
;;; Typical output:
;;; 	+-----------------+
;;; 	| eax = 1234 5678 |
;;; 	| ebx = 55FF 55FF |
;;; 	| ecx = FEDC BA98 |
;;; 	| edx = 0000 0000 |
;;; 	| esi = 1111 2222 |
;;; 	| edi = 2222 3333 |
;;; 	+-----------------+
;;; 	+-----------------+
;;; 	| eax = 1234 5678 |
;;; 	| ebx = 55FF 55FF |
;;; 	| ecx = FEDC BA98 |
;;; 	| edx = 0000 0000 |
;;; 	| esi = 1111 2222 |
;;; 	| edi = 2222 3333 |
;;; 	+-----------------+
;;;
;;; To assemble, link and run:
;;;   nasm -f elf hw8aSol.asm
;;;   ld -melf_i386 hw8aSol.o -o hw8aSol
;;;   ./hw8aSol
;;; ---------------------------------------------------------

%include "dumpRegs.asm"
	
		section	.text
		global	_start

_start:

;;; Initialize the registers
		mov	eax, 0x12345678
		mov	ebx, 0x55FF55FF
		mov	ecx, 0xFEDCBA98
		mov	edx, 0x00000000
		mov	esi, 0x11112222
		mov	edi, 0x22223333

;;; dump them twice to verify that no registers gets modified...
	        call    dumpRegs
		call	dumpRegs


;;; exit back to OS
		mov	ebx, 0
		mov	eax, 1
		int	0x80


hw8asol.asm


;;; ---------------------------------------------------------
;;; hw8aSol.asm
;;; D. Thiebaut
;;; 11/13/12
;;; This program supports several functions that allow the user
;;; to dump the contents of the main 6 registers (eax, ebx, ecx,
;;; edx, esi and edi) to the screen.  Great for debugging without
;;; a debugger.
;;;
;;; Typical output:
;;; 	+-----------------+
;;; 	| eax = 1234 5678 |
;;; 	| ebx = 55FF 55FF |
;;; 	| ecx = FEDC BA98 |
;;; 	| edx = 0000 0000 |
;;; 	| esi = 1111 2222 |
;;; 	| edi = 2222 3333 |
;;; 	+-----------------+
;;; 	+-----------------+
;;; 	| eax = 1234 5678 |
;;; 	| ebx = 55FF 55FF |
;;; 	| ecx = FEDC BA98 |
;;; 	| edx = 0000 0000 |
;;; 	| esi = 1111 2222 |
;;; 	| edi = 2222 3333 |
;;; 	+-----------------+
;;;
;;; To assemble, link and run:
;;;   nasm -f elf hw8aSol.asm
;;;   ld -melf_i386 hw8aSol.o -o hw8aSol
;;;   ./hw8aSol
;;; ---------------------------------------------------------

		section	.data
hex		db	"0123456789ABCDEF"
regs		db	"axbxcxdxsidi"
line		db	"+-----------------+", 10
string		db	"| exx = .... .... |", 10
lineLen 	equ	$-string
reg		equ	string+3
word1		equ	string+8

		section	.text
		global	_start

_start:

;;; Initialize the registers
		mov	eax, 0x12345678
		mov	ebx, 0x55FF55FF
		mov	ecx, 0xFEDCBA98
		mov	edx, 0x00000000
		mov	esi, 0x11112222
		mov	edi, 0x22223333

;;; dump them twice to verify that no registers gets modified...
	        call    dumpRegs
		call	dumpRegs


;;; exit back to OS
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; ---------------------------------------------------------
;;; dumpRegs: dumps the contents of the 6 main registers (eax
;;; ebx, ecx, edx, esi and edi) in a box on the screen.
;;; the screen.  Does not modify any register
;;; ---------------------------------------------------------
dumpRegs:	pushad

;;; put all the registers to print in the stack.  The loop
;;; will pop each one, one at a time, once per loop.
	
		push	edi
		push	esi
		push	edx
		push	ecx
		push	ebx
		push	eax

;;; print top bar
		call	printBar
	
;;; prepare to loop 6 times (6 registers )
		mov	ecx, 6
		mov	esi, 0

.for		pop	ebx			;get value of register to convert from stack
		push	ecx			;save loop counter
		lea	eax, [regs + esi*2]	;get address of string representing register
	
		mov	ax, word [eax] 		;ax gets "ax" or "bx" or "cx" or ... "di"
		mov	word[reg], ax		;modify string with name of register
	
		mov	edx, word1 		;edx points to buffer where to store hex digits
						;ebx contains register to convert
		call 	storeDWord		;store hex equivalent of ebx in string
	
		mov	ecx, string 		;print the whole string
		mov	edx, lineLen
		call	printInt80
		inc	esi			;index into register names incremented
		pop	ecx			;get loop counter back
		loop	.for

;;; print bottom bar
		call 	printBar
	
		popad
		ret

;;; ---------------------------------------------------------
;;; storeDWord: gets
;;; 	ebx: register to convert
;;; 	edx: address where to put information
;;; ---------------------------------------------------------
		
storeDWord:	rol	ebx, 16			;bring most sig word in least sig word
		call	storeWord
	
		inc	edx			;make edx skip space in string
	
		rol	ebx, 16			;get lower byte back in least sig pos
		call	storeWord
		
		ret

;;; ---------------------------------------------------------
;;; storeWord: gets
;;;     bx: word to convert
;;; 	edx: address where to put information. edx incremented by 4
;;; ---------------------------------------------------------
storeWord:	rol	bx, 8			;put most sig byte of bx in lower position
		call	storeByte		;and convert it.  Store it in where edx 
						;points to. 
		rol	bx, 8			;same with lower nybble
		call	storeByte
		ret
	
;;; ---------------------------------------------------------
;;; storeByte: gets
;;;     bl: byte to convert
;;; 	edx: address where to store information.  edx incremented by 2 automatically
;;; ---------------------------------------------------------
storeByte:	push	ebx
		push	eax
	
		rol	bl, 4			;get upper nybble in lower position (LSB)
		mov	al, bl			;play with al now
		and	eax, 0x0000000F		;clear all but the least significant nybble
		add	eax, hex		;get ascii in hex array equivalentn to nybble
		mov	al, [eax] 		;hex digit now in bl
		mov	byte [edx], al		;store ascii in string
		inc	edx

		rol	bl, 4			;get lower nybble back
		mov	al, bl			;play with al
		and	eax, 0x0000000F
		add	eax, hex
		mov	al, [eax]
		mov	byte [edx], al
		inc	edx
	
		pop	eax
		pop	ebx
		ret
		
;;; ---------------------------------------------------------
;;; printInt80: prints on the screen the string whose address
;;; is in ecx and length in edx.
;;; does not modify registers
;;; ---------------------------------------------------------
printInt80:	push	eax
		push	ebx
	
		mov	eax, 4
		mov	ebx, 1
		int	0x80
	
		pop	ebx
		pop	eax
		ret
	
;;; ---------------------------------------------------------
;;; printBar: prints the horizontal bar
;;; does not modify registers
;;; ---------------------------------------------------------
printBar:	push	ecx
		push	edx
	
		mov	ecx, line
		mov	edx, lineLen
		call	printInt80
	
		pop	edx
		pop	ecx
		ret


hw9a.asm


;;; hw9.asm
;;; D. Thiebaut
;;; displays a simple hello msg on the screen using int 0x80, 
;;  in a loop that goes around "many" times!
;;; To assemble, link and run:
;;;
;;; nasmld hw9
;;;  

EXIT    equ     1
READ    equ     3 
WRITE   equ      4
STDOUT  equ     1

        
       ;; -------------------------------------
       ;; data segment
       ;; -------------------------------------
       section .data
msg     db      "hello world!",0x0a 
MSGLEN  equ     $-msg
       
       ;; -------------------------------------
       ;; code segment
       ;; -------------------------------------
       section .text
       global  _start
       
_start: mov     ecx, 0          ; get ready to loop

for:    mov     eax,WRITE       ; print message 
       mov     ebx,STDOUT      ; to screen
       push    ecx        
       mov     ecx,msg         ; address of msg
       mov     edx,MSGLEN      ; # chars to print

       int     0x80            ; ask os to pring msg
       pop     ecx
;;;    push    ecx
       loop    for

       ;; exit
       
       mov     eax,EXIT        ; return to OS
       mov     ebx,0
       int     0x80


hw9.asm


;;;     nasm -f elf -F stabs hw9.asm ; ld -melf_i386 -o hw9 hw9.o ; ./hw9

        %include "asm_io.inc"

        section .data

        ;; live cells are 1 and dead cells are 0
        ;; the initial population is 32 out of 78 cells
        ;; with two buffer cells filled with 0
arr     dd      0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0
        dd      0,1,1,0,1,1,0,0,0,0,0,0,0,1,1,0
        dd      0,0,0,0,0,1,1,0,1,0,1,0,0,0,0,0
        dd      1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,0
        dd      0,0,0,1,1,1,0,1,0,1,1,0,0,0,0,0

arrStart        equ     $-arr

        ;; This array holds the value of the neighbors computed
        ;; for each cell
vals    dd      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        dd      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        dd      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        dd      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        dd      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

valsStart       equ     $-vals

fate    dd      0, 1, 0         ;fate of cells with 0, 1 or 2 neighbors
liveDead        dd      " X "   ;look up which char to print based on index




	section .text
        global asm_main

;;; prints a " " for each dead cell and a "X" for each live one
print_gen:
        pushad

        popad
        ret

;;; Computes the next generation of a cell
new_gen:
        push    ebp             ;save old stack loc
        mov     ebp, esp
        pushad
        section .data           ;creat temporary n-1 and n+1
tempmin         dd      0
tempplus        dd      0
        section .text
        mov     eax, [ebp+8]    ;chec to see if we are getting the index
        inc     eax
        call    print_int
        popad
        pop     ebp
        ret	4

asm_main:
        mov     ecx, 0x4a       ;loop for 78  cells
.for:
;;      inc     ecx             ;allow counter to reflect buffer zone
        push    ecx             ;give index to function
        call    new_gen
        ;; dec  ecx             ;;return counter to it's proper value
        loop    .for

        ret


hwtest.asm


;;; hwtest.asm
     ;;; a simple demo program to test I/O with
     ;;; a C "wrapper" program

     %include "asm_io.inc"

             ;; -------------------------
             ;; data segment
             ;; -------------------------
             section .data
     msg     db      "Hello! Please enter an integer number: ",0x00
     msg2    db      "You have entered ",0x00
     x       dd      0

             ;; -------------------------
             ;; code area
             ;; -------------------------
             section .text
             global  asm_main
     asm_main:       

             mov     eax,msg               ; pass address of the string msg in eax
             call    print_string          ; call a function in asm_io library
                                           ; that will print the string msg

             call    read_int              ; call a function that reads an
             mov     [x], eax              ; integer from the keyboard and
                                           ; returns it in eax.  Save returned
                                           ; value in variable x

             mov     eax,msg2              ; print the string msg2
             call    print_string          ; ("you have entered")

             mov     eax,[x]               ; get integer user entered
             call    print_int             ; pass it via eax and call the
                                           ; function specialized in printing
                                           ; integer numbers

             call    print_nl              ; call the function that prints
                                           ; a new blank line

             ;; return to C program

             ret


lab1.asm


;;; ; program_name.asm
;;; ; your name
;;; ;
;;; ; a description of the program
;;; ;
;;; ; to assemble and run:
;;; ;
;;; ;     nasm -f elf -F  stabs program.asm
;;; ;     ld -o program program.o
;;; ;     ./program
;;; ; -------------------------------------------------------------------

	;; %include files here...



;;;  ------------------------------------------------------------
;;;  data areas
;;;  ------------------------------------------------------------

	section	.data

msg     db     "Welcome to csc231", 10
MSGLEN  equ    $-msg
;;;  ------------------------------------------------------------
;;;  code area
;;;  ------------------------------------------------------------

	section	.text
	global	_start

_start:
        mov    eax, 4
        mov    ebx, 1
        mov    ecx, msg ; use the same name as the string in the data section
        mov    edx, MSGLEN	; # of chars in string
        int    0x80

;;;  exit()

	mov	eax,1
	mov	ebx,0
	int	0x80		; final system call


loop1.asm


;;; hwtest.asm
;;; a simple demo program to test I/O with


		%include "asm_io.inc"

        ;; -------------------------
        ;; data segment
        ;; -------------------------
        section .data


        ;; -------------------------
        ;; code area
        ;; -------------------------
        section .text
        global  asm_main
asm_main:       

	mov	ecx, 100
	mov	eax, 1

for:	
	call	print_int
	call	print_nl
	inc	eax
	loop	for
	
        ret


loop2.asm


;;; hwtest.asm
;;; a simple demo program to test I/O with


		%include "asm_io.inc"

        ;; -------------------------
        ;; data segment
        ;; -------------------------
        section .data


        ;; -------------------------
        ;; code area
        ;; -------------------------
        section .text
        global  asm_main
asm_main:       

	mov	ecx, 100
	mov	eax, 1
	mov	ebx, 0
	
for:	add	ebx, eax
	call	print_int
	call	print_nl
	inc	eax
	loop	for

	call	print_nl
	mov	eax, ebx
	call	print_int
	
        ret


loop3.asm


;;; loop3.asm
;;; 


		%include "asm_io.inc"

        ;; -------------------------
        ;; data segment
        ;; -------------------------
        section .data
n1	dd	10
n2	dd	20

        ;; -------------------------
        ;; code area
        ;; -------------------------
        section .text
        global  asm_main
asm_main:       

	mov	ecx, dword[n2]
	sub	ecx, dword[n1]
	inc	ecx
	mov	eax, dword[n1]
	mov	ebx, 0
	
for:	add	ebx, eax
	call	print_int
	call	print_nl
	inc	eax
	loop	for

	call	print_nl
	mov	eax, ebx
	call	print_int
	
        ret


loop4.asm


;;; loop4.asm
;;; same as loop1.asm, but prints the
;;; numbers 10 per line.


		%include "asm_io.inc"

        ;; -------------------------
        ;; data segment
        ;; -------------------------
        section .data
space	db	" ", 0

        ;; -------------------------
        ;; code area
        ;; -------------------------
        section .text
        global  asm_main
	
asm_main:
;;; n = 1
;;; for i in range( 1, 11 ): # loops 10 times
;;;     for j in range( 1, 11 ): # loops 10 times
;;; 	    print( n, end=" " )
;;; 	    n += 1
;;;     print()
;;; 


;;; n = 1
	mov	eax, 1

	mov	ecx, 10
	
for1:	mov	edx, ecx	; save ecx of loop1

	mov	ecx, 10
	
for2:	call	print_int	; print n
	mov	ebx, eax	; save n
	
	mov	eax, space	; print space
	call	print_string
	mov	eax, ebx	; restore n
	inc	eax		; n <- n+1
	
	loop	for2

	call	print_nl

	mov	ecx, edx
	loop	for1

	call	print_nl
        ret


loopDemo.asm


;;; skel.asm
;;; D. Thiebaut
;;;
;;; 
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs skel.asm
;;; 	ld -melf_i386 -o skel skel.o
;;; 	./skel
;;;

		section	.data
;;; put your variables here...

	
		section	.text
		global	_start
_start:	
		mov	ecx, 0
for1:		loop	for1

		loop	for1
		loop	for1
	
;;; put your code here

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


loopExample.asm


;;; loopExample.asm
;;;a simple demo program to show how to implement a counting loop
;;;Uses the driver.c program as a C "wrapper" 
	
		%include "asm_io.inc"

             ;; -------------------------
             ;; data segment
             ;; -------------------------
             section .data
count        dd	0

             ;; -------------------------
             ;; code area
             ;; -------------------------
             section .text
             global  asm_main
asm_main:       
	     
	     mov	ecx, 10			; get ready to loop 10 times
for:	     mov	eax, dword[count]	; load counter
	     call	print_int		; print it
             call    	print_nl		; new line

	     inc	dword[count] 		; increment counter
	     loop	for			; keep looping until done

             ;; return to C program

             ret


manymoves.asm


;;; skel.asm
;;; D. Thiebaut
;;;
;;; 
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs skel.asm
;;; 	ld -melf_i386 -o skel skel.o
;;; 	./skel
;;;

		section	.data
a		db	0
b		dw	0
c		dd	0

	
		section	.text
		global	_start
_start:
		mov	eax, 3
		mov	ax, 3
		mov	al, 3
		mov	ah, 3

		mov	eax, c
		mov	eax, dword[c]
		mov	ax, word[b]
		mov	al, byte[a]
		mov	ah, byte[a]

		mov	ebx, 3
		mov	bx, 3
		mov	bl, 3
		mov	bh, 3

		mov	ebx, c
		mov	ebx, dword[c]
		mov	bx, word[b]
		mov	bl, byte[a]
		mov	bh, byte[a]
	
		mov	al, bl
		mov	cx, dx
		mov	edx, ebx

;;; put your code here

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


mickeyMouse.asm


;;; mickeyMouse.asm
;;; D. Thiebaut
;;;
;;; Display "Hello Mickey" on the screen,
;;; followed by 3 line-feeds.
;;;
;;; To assemble, link, and run:
;;; 
;;; nasm -f elf -F stabs mickeyMouse.asm
;;; ld -melf_i386 -o mickeyMouse mickeyMouse.o
;;; ./mickeyMouse
;;;

		section	.data
Hello		db	"Hello Mickey"
Mouse	        db      " Mouse!"
lflflf		db	10, 10, 10


		section	.text
		global	_start
_start:	

;;; print "Hello Mickey"
		mov	eax, 4			; write
		mov	ebx, 1			; stdout
		mov	ecx, Hello		; "Hello Mickey"
		mov	edx, Mouse-Hello	; # char between Mouse and Hello
		int 	0x80

;;; print 3 line-feed chars

		mov	eax, 4			; write
		mov	ebx, 1			; stdout
		mov	ecx, lflflf		; address of 3 line-feed chars
		mov	edx, 3			; print 3 chars
		int 	0x80
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


midTerm.asm


;;; hwtest.asm
     ;;; a simple demo program to test I/O with
     ;;; a C "wrapper" program

     %include "asm_io.inc"

             ;; -------------------------
             ;; data segment
             ;; -------------------------
             section .data
     msg     db      "Hello! Please enter an integer number: ",0x00
     msg2    db      "You have entered ",0x00
     x       dd      0

             ;; -------------------------
             ;; code area
             ;; -------------------------
             section .text
             global  asm_main
     asm_main:       

	mov	ecx, 10
	mov	eax, 0
for2:	call	print_int
	mov	eax, ecx
	dec 	ecx
	loop	for2

	call	print_nl
	
        ret


minilab1.asm


;;; minilab1.asm
;;; D. Thiebaut
;;; prints this string on the screen:
;;;
;;; 	*********************************
;;;     * Welcome to CSC231             *
;;;     * Home of the Assembly Language *
;;;     *********************************


	section	.data

msg	db	"*********************************", 10
	db	"* Welcome to CSC231             *", 10
	db	"* Home of the Assembly Language *", 10	
	db	"*********************************", 10, 10
	
msgLen	equ	$-msg

	section	.text
	global	_start
_start:
	mov	eax,4
	mov	ebx,1
	mov	ecx,msg
	mov	edx,msgLen
	int	0x80

;;; exit
	mov	eax,1
	mov	ebx,0
	int	0x80


minilab1_v1.asm


;;; minilab1.asm
;;; D. Thiebaut
;;; prints this string on the screen:
;;;
;;; 		*********************************
;;;     * Welcome to CSC231             *
;;;     * Home of the Assembly Language *
;;;     *********************************


	section	.data

msg	db	"*********************************", 10
	db	"* Welcome to CSC231             *", 10
	db	"* Home of the Assembly Language *", 10	
	db	"*********************************", 10, 10
	
msgLen	equ	$-msg

	section	.text
	global	_start
_start:
	mov	eax,4
	mov	ebx,1
	mov	ecx,msg
	mov	edx,msgLen
	int	0x80

;;; exit
	mov	eax,1
	mov	ebx,0
	int	0x80


minilab1_v2.asm


;;; minilab1.asm
;;; D. Thiebaut
;;; prints this string on the screen:
;;;
;;; 	*********************************
;;;     * Welcome to CSC231             *
;;;     * Home of the Assembly Language *
;;;     *********************************


	section	.data

msg	db	"*********************************", 10
msgLen1	equ	$-msg	
	db	"* Welcome to CSC231             *", 10
	db	"* Home of the Assembly Language *", 10	
msgLen2	equ	$-msg
	
	section	.text
	global	_start
_start:
	
;;; print first 3 lines
	mov	eax,4
	mov	ebx,1
	mov	ecx,msg
	mov	edx,msgLen2
	int	0x80

;;; print first line back, to close box
	mov	eax,4
	mov	ebx,1
	mov	ecx,msg
	mov	edx,msgLen1
	int	0x80

;;; exit
	mov	eax,1
	mov	ebx,0
	int	0x80


movStrings1.asm


;;; movString1s.asm
;;; D. Thiebaut
;;;
;;; 
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs movString1s.asm
;;; 	ld -melf_i386 -o movStrings1 movStrings1.o
;;; 	./movStrings1
;;;

		section	.data
msg1		db	"Smith College", 10
msg1Len		equ	$-msg1
msg2		db	".............", 10
	
		section	.text
		global	_start
_start:	

;;; print msg1
		mov	eax, 4
		mov	ebx, 1
		mov 	ecx, msg1
		mov	edx, msg1Len
		int	0x80

;;; print msg2
		mov	eax, 4
		mov	ebx, 1
		mov 	ecx, msg2
		mov	edx, msg1Len
		int	0x80
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


movStrings2.asm


;;; movString1s.asm
;;; D. Thiebaut
;;;
;;; This version copies msg1 to msg2
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs movString1s.asm
;;; 	ld -melf_i386 -o movStrings2 movStrings2.o
;;; 	./movStrings2
;;;

		section	.data
msg1		db	"Smith College", 10
msg1Len		equ	$-msg1
msg2		db	".............", 10
	
		section	.text
		global	_start
_start:	

;;; print msg1
		mov	eax, 4
		mov	ebx, 1
		mov 	ecx, msg1
		mov	edx, msg1Len
		int	0x80

;;; print original msg2
		mov	eax, 4
		mov	ebx, 1
		mov 	ecx, msg2
		mov	edx, msg1Len
		int	0x80

;;; copy msg1 into msg2
		mov	al, byte [msg1]
		mov	byte[msg2], al

		mov	al, byte [msg1+1]
		mov	byte[msg2+1], al

		mov	al, byte [msg1+2]
		mov	byte[msg2+2], al

		mov	al, byte [msg1+3]
		mov	byte[msg2+3], al

		mov	al, byte [msg1+4]
		mov	byte[msg2+4], al

		mov	al, byte [msg1+5]
		mov	byte[msg2+5], al

		mov	al, byte [msg1+6]
		mov	byte[msg2+6], al

		mov	al, byte [msg1+7]
		mov	byte[msg2+7], al

		mov	al, byte [msg1+8]
		mov	byte[msg2+8], al

		mov	al, byte [msg1+9]
		mov	byte[msg2+9], al

		mov	al, byte [msg1+10]
		mov	byte[msg2+10], al

		mov	al, byte [msg1+11]
		mov	byte[msg2+11], al

		mov	al, byte [msg1+12]
		mov	byte[msg2+12], al

;;; print new msg2
		mov	eax, 4
		mov	ebx, 1
		mov 	ecx, msg2
		mov	edx, msg1Len
		int	0x80

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


movStrings3.asm


;;; movStrings3.asm
;;; D. Thiebaut
;;;
;;; This version copies msg1 to msg2, one word at a time...
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs movString1s.asm
;;; 	ld -melf_i386 -o movStrings3 movStrings3.o
;;; 	./movStrings3
;;;

		section	.data
msg1		db	"Smith College", 10
msg1Len		equ	$-msg1
msg2		db	".............", 10
	
		section	.text
		global	_start
_start:	

;;; print msg1
		mov	eax, 4
		mov	ebx, 1
		mov 	ecx, msg1
		mov	edx, msg1Len
		int	0x80

;;; print original msg2
		mov	eax, 4
		mov	ebx, 1
		mov 	ecx, msg2
		mov	edx, msg1Len
		int	0x80

;;; copy msg1 into msg2
		mov	ax, word [msg1]
		mov	word[msg2], ax

		mov	ax, word [msg1+2]
		mov	word[msg2+2], ax
	
		mov	ax, word [msg1+4]
		mov	word[msg2+4], ax
	
		mov	ax, word [msg1+6]
		mov	word[msg2+6], ax
	
		mov	ax, word [msg1+8]
		mov	word[msg2+8], ax
	
		mov	ax, word [msg1+10]
		mov	word[msg2+10], ax

		mov	ax, word [msg1+12]
		mov	word[msg2+12], ax



;;; print new msg2
		mov	eax, 4
		mov	ebx, 1
		mov 	ecx, msg2
		mov	edx, msg1Len
		int	0x80

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


movStrings4.asm


;;; movStrings4.asm
;;; D. Thiebaut
;;;
;;; This version copies msg1 to msg2, one doubleword at a time...
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs movString1s.asm
;;; 	ld -melf_i386 -o movStrings4 movStrings4.o
;;; 	./movStrings4
;;;
;;; ------------------------------------------------------------------
;;; WARNING!  This program has a bug!  Can you figure out where it is?
;;; Even better, can you expose the bug, as the output of this program
;;; seems correct?
;;; Here's the output:
;;; 
;;; Smith College
;;; .............
;;; Smith College
;;; 
;;; ------------------------------------------------------------------
	

		section	.data
msg1		db	"Smith College", 10
msg1Len		equ	$-msg1
msg2		db	".............", 10
	
		section	.text
		global	_start
_start:	

;;; print msg1
		mov	eax, 4
		mov	ebx, 1
		mov 	ecx, msg1
		mov	edx, msg1Len
		int	0x80

;;; print original msg2
		mov	eax, 4
		mov	ebx, 1
		mov 	ecx, msg2
		mov	edx, msg1Len
		int	0x80

;;; copy msg1 into msg2
		mov	eax, dword [msg1]
		mov	dword[msg2], eax

		mov	eax, dword [msg1+4]
		mov	dword[msg2+4], eax
	
		mov	eax, dword [msg1+8]
		mov	dword[msg2+8], eax
	
		mov	eax, dword [msg1+12]
		mov	dword[msg2+12], eax



;;; print new msg2
		mov	eax, 4
		mov	ebx, 1
		mov 	ecx, msg2
		mov	edx, msg1Len
		int	0x80

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


printBinary.asm


;;; printBinary.asm
;;; D. Thiebaut
;;; prints a number in binary

%include "asm_io.inc"

        ;; -------------------------
        ;; data segment
        ;; -------------------------
        section .data
x	dd	0xff55aa11
	
        ;; -------------------------
        ;; code area
        ;; -------------------------
        section .text
        global  asm_main
asm_main:       
	mov	ebx, dword[x]	; number to print
	mov	ecx, 32		; # of bits
	
for:	shl	ebx, 1
	mov	eax, 0		; eax <-- 0
;;; 	xor	eax, eax
	adc	eax, 0		; eax <-- 0 if no carry, 1 if carry
	call	print_int
	loop	for

	call	print_nl

        ;; return to C program
	
        ret


printInteger.asm


;;; printInteger.asm
;;; D. Thiebaut
;;;
;;; Display "Hello there!" on the screen
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs helloWorld.asm
;;; 	ld -melf_i386 -o helloWorld helloWorld.o
;;; 	./helloWorld
;;;

		section	.data
char		db	'x'
	
		section	.text
		global	_start
_start:	

;;; print message
		mov	eax, 123456789
		call	printInt
		call	printNl

		mov	eax, -1024
		call	printInt
		call	printNl

		mov	eax, -1
		call	printInt
		call	printNl
	
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; -------------------------------------------------------------
;;; printNl: prints a \n
;;; -------------------------------------------------------------
printNl:	pushad
		mov	byte[char], 10
		mov	eax, 4
		mov	ebx, 1
		mov	ecx, char
		mov	edx, 1
		int	0x80
		popad
		ret
	
;;; -------------------------------------------------------------
;;; printInt
;;; gets integer to print in eax and prints it in decimal
;;; -------------------------------------------------------------
printInt:	pushad
		mov	ecx, 0		;get ready to count digits in number
.for1:	
		mov	edx, 0		;will divide edx:eax by 10.  edx gets 0
		mov	ebx, 10		;divisor is 10
		div	ebx		;edx <-- remainder, eax <-- quotient
	
		push	dx		;save remainder between 0 and 9.
		inc	ecx		;one more digit found
		cmp	eax, 0		;is there something left?
		jne	.for1		;if yes, go back and get more digits

		;;; done finding digits. ecx has the number
		;;; of digits, and the stack has the numbers
	
.for2:		pop	ax		;get digit between 0 and 9
		add	al, '0'		;transform into Ascii
		mov	byte[char], al	;put it in string and print string
		mov	eax, 4
		mov	ebx, 1
		mov	edx, 1
		push	ecx		;save digit counter
		mov	ecx, char
		int	0x80
		pop	ecx
	
		loop	.for2		;go back for more digits
	
		popad
		ret


printStars2.asm


;;; printStars.asm
;;; D. Thiebaut
;;;
;;; 
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs printStars.asm
;;; 	ld -melf_i386 -o printStars printStars.o
;;; 	./printStars
;;;

		section	.data

stars 		db	0x0a, "******************************"
starsLen	equ	$-stars
	
addr		dd	stars
count		dd	starsLen
	
		section	.text
		global	_start
_start:	
		mov	ecx, dword[count]
	
for:		mov	dword[count], ecx			
		mov	eax, 4
		mov	ebx, 1
		mov	ecx, stars
		mov	edx, starsLen
		sub	edx, dword[count]
		int	0x80

		mov	ecx, dword[count]
		loop	for
	
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


printStars.asm


;;; printStars.asm
;;; D. Thiebaut
;;;
;;; 
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs printStars.asm
;;; 	ld -melf_i386 -o printStars printStars.o
;;; 	./printStars
;;;

		section	.data

stars 		db	0x0a, "******************************"
starsLen	equ	$-stars
	
addr		dd	stars
count		dd	starsLen
	
		section	.text
		global	_start
_start:	
		mov	ecx, dword[count]
	
for:		mov	dword[count], ecx			
		mov	eax, 4
		mov	ebx, 1
		mov	ecx, stars
		mov	edx, dword[count]
		int	0x80

		mov	ecx, dword[count]
		loop	for
	
;;; exit
		jmp	next
next:		
		mov	ebx, 0
		mov	eax, 1
		int	0x80


recursFib2.asm


;;; recurseFib2.asm
;;; D. Thiebaut
;;; A possible solution for Homework 10
;;; Computes the nth term of the Fibonacci sequence using
;;; a (very unefficient) recursive function.  In this version
;;; we remove the tail-recursion for 9 levels of the recursion
;;; tree by using a look-up table for the first 9 values of
;;; the Fib series
;;; The amount of stack required is defined by what is pushed
;;; in the stack when the function is called: 3 dwords which
;;; include the return address, plus the stuff the function pushes.
;;; if stopping condition is reached, only ebp is pushed, otherwise
;;; 2 more dwords are pushed.
;;; For N=1, the amount of stack used is 3 + 1  = 4 dwords
;;; For N=2, same: 4 dwords
;;; For N=9, same: 4 dwords
;;; For N=10, 4 + 4 = 8 dwords
;;; For N=11, 4 + 4 + 4 = 12 dwords
;;; For N=n, (n-8) * 4 dwords
;;;
	
%include "dumpRegs.asm"
	
	section	.data
FibTable	dd		0,1,1,2,3,5,8,13,21,34,55


	section .text

	global	_start

_start:	push	eax		; make room
	push	dword 46	; compute fib(20)
	call	fib
	pop	eax		; get fib(20)
	call	dumpRegs	; display the registers (in hex)

	mov	eax, 1
	mov	ebx, 0
	int	0x80


;;; ---------------------------------------------------------------
;;; fib: a recursive function for computing fib(n)=fib(n-1)+fib(n-2)
;;; The tail recursion is cut for n<=9, where a look-up table is used
;;; instead.
;;; Stack:
;;; [ebp+12]: returned value
;;; [ebp+8]: N
;;; [ebp+4]: return address
;;; [ebp]: old ebp

fib:	push	ebp
	mov	ebp, esp
	
;;; 	ebp+8	is N
;;; 	ebp+12	is return value
	
	mov	eax, [ebp+8]		; get N
	cmp	eax, 9			; recurse for N>9
	jg	.recurse		
	mov	eax, dword[FibTable+eax*4] ;otherwise look up
	mov	dword [ebp+12], eax	 ;the result in a table
	pop	ebp
	ret	4
	
.recurse:
	push	eax			;make room for return value
	dec	eax			;N-1
	push	eax			;pass N-1
	call	fib			;to fib
					;we don't pop the result yet...
	
	mov	eax, [ebp+8]		;get N
	sub	eax, 2			;N-2
	push	eax			;make room for result
	push	eax			;pass N-2
	call	fib			;call fib

	pop	eax			;pop result for fib(N-2)
	pop	ebx			;pop result for fib(N-1)
	add	eax, ebx		;sum up
	mov	dword [ebp+12], eax	;put result in stack

	pop	ebp			;return
	ret	4


recursFib.asm


%include "dumpRegs.asm"
	
	section	.data



	section .text

	global	_start

_start:	push	eax		; make room
	push	dword 10	; compute fib(20)
	call	fib
	pop	eax		; get fib(20)
	call	dumpRegs

	mov	eax, 1
	mov	ebx, 0
	int	0x80


fib:	push	ebp
	mov	ebp, esp
;;; 	ebp+8	is N
;;; 	ebp+12	is return value
	mov	eax, [ebp+8]
	cmp	eax, 2
	jg	.recurse
	mov	dword [ebp+12], 1
	pop	ebp
	ret	4
.recurse:
	push	eax
	dec	eax
	push	eax
	call	fib

	mov	eax, [ebp+8]
	sub	eax, 2
	push	eax
	push	eax
	call	fib

	pop	eax
	pop	ebx
	add	eax, ebx
	mov	dword [ebp+12], eax

	pop	ebp
	ret	4


reviewSumTwoVars.asm


;;; reviewSumTwoVars.asm
;;; D. Thiebaut
;;;
;;; in C++
;;; ======
;;; 
;;; int a = 2, b = 3, res = 0;
;;; sum( a, b, &res );
;;;
;;; void sum( int x, int y, int* z ) {
;;;   *z = x + y;
;;; }
;;;
;;; same code in assembly:  look below
;;;

%include "dumpRegs.asm"

	section	.data
a	dd	2
b	dd	3
res	dd	0


	section	.text
	global	_start
_start:
;;; example of passing by value and by reference via registers
;;; ----------------------------------------------------------

	mov	eax, [a]
	mov	ebx, [b]
	mov	ecx, res
	call	sum1

	mov	edx, [res]
	call	dumpRegs

;;; example of passing by value and by reference via the stack
;;; ----------------------------------------------------------
	mov	dword[res], 0	;reset what's in res
	
	push	dword [a]
	push	dword [b]
	push	dword res
	call	sum2

	mov	edx, [res]
	call	dumpRegs

;;; exit
	mov	eax, 1
	mov	ebx, 0
	int	0x80

;;; ----------------------------------------------------------
;;; sum1: gets 2 values in eax and ecx, and stores their sum
;;; at dword [ecx]
;;; Does not modify registers
;;; ----------------------------------------------------------
sum1:	mov	[ecx], eax
	add	[ecx], ebx
	ret

;;; ----------------------------------------------------------
;;; sum2: gets 2 values in the stack and a reference and 
;;; stores the sum of the values at that reference.
;;; Does not modify registers
;;; ----------------------------------------------------------
sum2:	push	ebp
	mov	ebp, esp
	push	eax
	push	ebx
	
	mov	eax, [ebp + 12]
	add	eax, [ebp + 16]
	mov	ebx, [ebp + 8]
	mov	[ebx], eax

	pop	ebx
	pop	eax
	pop	ebp
	ret	3*4


simpleAdd.asm


		section	.data

a          dd          3
b          dd          5
result     dd          0

	
		section	.text
		global	_start
_start:	


nop
	          nop
	          mov          eax, dword[a]
	          add          eax, dword[b]
	          mov          dword[result], eax
	

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


skel2.asm


;;; ; program_name.asm
;;; ; your name
;;; ;
;;; ; a description of the program
;;; ;
;;; ; to assemble and run:
;;; ;
;;; ;     nasm -f elf -F  stabs program.asm
;;; ;     ld -o program program.o
;;; ;     ./program
;;; ; -------------------------------------------------------------------

	;; %include files here...



;;;  ------------------------------------------------------------
;;;  data areas
;;;  ------------------------------------------------------------

	section	.data


;;;  ------------------------------------------------------------
;;;  code area
;;;  ------------------------------------------------------------

	section	.text
	global	_start

_start:


;;;  (add your code here!!!!)




;;;  exit()

	mov	eax,1
	mov	ebx,0
	int	0x80		; final system call


skel.asm


;;; skel.asm
;;; D. Thiebaut
;;;
;;; 
;;;
;;; To assemble, link, and run:
;;; 	nasm -f elf -F stabs skel.asm
;;; 	ld -melf_i386 -o skel skel.o
;;; 	./skel
;;;

		section	.data
;;; put your variables here...

	
		section	.text
		global	_start
_start:	

;;; put your code here

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80


sumFloat1.asm


; sumFloat1.asm   use "C" printf on float
; 
; Assemble:	nasm -f elf float1.asm
; Link:		gcc -m32 -o float1 float1.o
; Run:		./float1
; Adds x to y and store result in z.  Prints
; z using printf.
; This program uses the external printf C  function which requires
; a format string defining what to print, and a variable number of
; variables to print.


        extern printf                   ; the C function to be called

        SECTION .data                   ; Data section

msg     db      "sum = %e",0x0a,0x00
x	dd	1.5
y	dd	2.5
z	dd	0
temp	dq	0
	
	SECTION .bss
		
flttmp:	resq 1			        ; 64-bit temporary for printing flt1
	
        SECTION .text                   ; Code section.

        global	main		        ; "C" main program 
main:				        ; label, start of main program
	
	fld	dword [x]	        ; need to convert 32-bit to 64-bit
	fld	dword [y]
	fadd
	fst	dword [z]		; store sum in z
	fstp	qword [temp]            ; store in 64-bit temp and pop stack top

		 
	push	dword [temp+4] 		; push temp as 2 32-bit words
	push	dword [temp]
        push    dword msg		; address of format string
        call    printf			; Call C function
        add     esp, 12			; pop stack 3*4 bytes

        mov     eax, 1			; exit code, 0=normal
	mov	ebx, 0
        int	0x80			;


sumFloat2.asm


; sumFloat1.asm   use "C" printf on float
; 
; Assemble:	nasm -f elf float1.asm
; Link:		gcc -m32 -o float1 float1.o
; Run:		./float1
; Adds x to y and store result in z.  Prints
; z using printf.
; This program uses the external printf C  function which requires
; a format string defining what to print, and a variable number of
; variables to print.
%include "dumpRegs.asm"

        extern printf                   ; the C function to be called

        SECTION .data                   ; Data section

msg     db      "sum = %e",0x0a,0x00
x	dd	1.5
y	dd	2.5
z	dd	0
temp	dq	0
	
	
        SECTION .text                   ; Code section.

        global	main		        ; "C" main program 
main:				        ; label, start of main program
	
	fld	dword [x]	        ; need to convert 32-bit to 64-bit
	fld	dword [y]
	fadd
	fstp	dword [z]		; store sum in z

	mov	eax, [z]
	call	dumpRegs		;just to see the binary version of z

	fld	dword [z]     		; transform z in 64-bit word
	fstp	qword [temp]            ; store in 64-bit temp and pop stack top

		 
	push	dword [temp+4] 		; push temp as 2 32-bit words
	push	dword [temp]
        push    dword msg		; address of format string
        call    printf			; Call C function
        add     esp, 12			; pop stack 3*4 bytes

        mov     eax, 1			; exit code, 0=normal
	mov	ebx, 0
        int	0x80			;


sumFloat3.asm


; sumFloat3.asm   use "C" printf on float
; 
; Assemble:	nasm -f elf float1.asm
; Link:		gcc -m32 -o float1 float1.o
; Run:		./float1
; Compute z = (x-1) * (y+3.5), where x is 1.5 and y is 2.5
; This program uses the external printf C  function which requires
; a format string defining what to print, and a variable number of
; variables to print.
%include "dumpRegs.asm"

        extern printf                   ; the C function to be called

        SECTION .data                   ; Data section

msg     db      "sum = %e",0x0a,0x00
x	dd	1.5
y	dd	2.5
z	dd	0
temp	dq	0
	
	
        SECTION .text                   ; Code section.

        global	main		        ; "C" main program 
main:				        ; label, start of main program

;;; compute x-1
	fld	dword [x]	        ; st0 <- x
	fld1				; st0 <- 1 st1 <- x
	fsub				; st0 <- x-1

;;; keep (x-1) in stack and compute y+3.5

	fld	dword [y]		; st0 <- y st1 <- x-1
	push	__float32__( 3.5 )	; put 32-bit float 3.5 in memory (actually in stack)
	fld	dword [esp]		; st0 <- 3.5 st1 <- y st2 <- x-1
	add	esp, 4			; undo push
	fadd				; st0 <- y+3.5 st1 <- x-1
	
	fadd				; st0 <- x-1 + y+3.5
	fst	dword [z]		; store sum in z


	fld	dword [z]     		; transform z in 64-bit word
	fstp	qword [temp]            ; store in 64-bit temp and pop stack top

		 
	push	dword [temp+4] 		; push temp as 2 32-bit words
	push	dword [temp]
        push    dword msg		; address of format string
        call    printf			; Call C function
        add     esp, 12			; pop stack 3*4 bytes

        mov     eax, 1			; exit code, 0=normal
	mov	ebx, 0
        int	0x80			;


sumFloat4.asm


; sumFloat4.asm   use "C" printf on float
; D. Thiebaut
; Assemble:	nasm -f elf sumFloat4.asm
; Link:		gcc -m32 -o sumFloat4 sumFloat4.o
; Run:		./sumFloat4
; Compute sum = sum of all the values in the array table.
; This program uses the external printf C  function which requires
; a format string defining what to print, and a variable number of
; variables to print.


        extern printf                   ; the C function to be called

        SECTION .data                   ; Data section
	
table		dd		 7.36464646465
		dd		 0.930984158273
		dd		 10.6047098049
		dd		 14.3058722306
		dd		 15.2983812149
		dd		 -17.4394255035
		dd		 -17.8120975978
		dd		 -12.4885670266
		dd		 3.74178604342
		dd		 16.3611827165
		dd		 -9.1182728262
		dd		 -11.4055038727
		dd		 4.68148165048
		dd		 -9.66095817322
		dd		 5.54394454154
		dd		 13.4203706426
		dd		 18.2194407176
		dd		 -7.878340987
		dd		 -6.60045833452
		dd		 -7.98961850398
N		equ		($-table)/4 	; number of items in table
	
;; sum of all the numbers  =  10.07955736
	
msg     db      "sum = %e",0x0a,0x00
temp	dq	0
sum	dd	0	
	
        SECTION .text                   ; Code section.

        global	main		        ; "C" main program 
main:				        ; label, start of main program

	mov	ecx, N
	mov	ebx, 0

	fldz				; st0 <- 0
for:	fld	dword [table + ebx*4]	; st0 <- new value, st1 <- sum of previous
	fadd				; st0 <- sum of new plus previous sum
	inc	ebx
	loop	for

;;; get sum back from FPU
	fstp	dword [sum]   		; put final sum in variable

;;; print resulting sum
	fld	dword [sum]    		; transform z in 64-bit word
	fstp	qword [temp]            ; store in 64-bit temp and pop stack top

		 
	push	dword [temp+4] 		; push temp as 2 32-bit words
	push	dword [temp]
        push    dword msg		; address of format string
        call    printf			; Call C function
        add     esp, 12			; pop stack 3*4 bytes

        mov     eax, 1			; exit code, 0=normal
	mov	ebx, 0
        int	0x80			;


sumFloat5.asm


; sumFloat5.asm   use "C" printf on float
; D. Thiebaut
; Assemble:	nasm -f elf sumFloat5.asm
; Link:		gcc -m32 -o sumFloat5 sumFloat5.o
; Run:		./sumFloat5
; Compute the max of an array of floats stored in table.
; This program uses the external printf C  function which requires
; a format string defining what to print, and a variable number of
; variables to print.


        extern printf                   ; the C function to be called

        SECTION .data                   ; Data section
	
max		dd		 0	
table		dd		 7.36464646465
		dd		 0.930984158273
		dd		 10.6047098049
		dd		 14.3058722306
		dd		 15.2983812149
		dd		 -17.4394255035
		dd		 -17.8120975978
		dd		 -12.4885670266
		dd		 3.74178604342
		dd		 16.3611827165
		dd		 -9.1182728262
		dd		 -11.4055038727
		dd		 4.68148165048
		dd		 -9.66095817322
		dd		 5.54394454154
		dd		 13.4203706426
		dd		 18.2194407176
		dd		 -7.878340987
		dd		 -6.60045833452
		dd		 -7.98961850398
N		equ		($-table)/4 	; number of items in table
	
;; sum of all the numbers  =  10.07955736
	
msg     db      "max = %e",0x0a,0x00
temp	dq	0

	
        SECTION .text                   ; Code section.

        global	main		        ; "C" main program 
main:				        ; label, start of main program
	mov	eax, dword [table]
	mov	dword [max], eax
	
	mov	ecx, N-1
	mov	ebx, 1

	fld	dword [table]		; st0 <- table[0]
	
for:	fld	dword [table + ebx*4]	; st0 <- new value, st1 <- current max
	fcom				; compare st0 to st1
	fstsw	ax			; store fp status in ax
	and	ax, 100000000b		;
	jz	newMax
	jmp	continue
	
newMax:	fxch	st1
	
continue:
	fcomp				; pop st0 (don't care about compare)

	inc	ebx			; point to next fp number
	loop	for

;;; get sum back from FPU
	fstp	dword [max]   		; st0 is max.  Store it in mem

;;; print resulting sum
	fld	dword [max]    		; transform z in 64-bit word
	fstp	qword [temp]            ; store in 64-bit temp and pop stack top

		 
	push	dword [temp+4] 		; push temp as 2 32-bit words
	push	dword [temp]
        push    dword msg		; address of format string
        call    printf			; Call C function
        add     esp, 12			; pop stack 3*4 bytes

        mov     eax, 1			; exit code, 0=normal
	mov	ebx, 0
        int	0x80			;


topDown1.asm


;;; towDown.asm
;;; in this version we expand printName
	
		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"

		section	.text
		global	_start
_start:	


		mov	eax, strings+0 ; eax <- address count+string
		call	printBoxName

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
		mov	al,byte[eax]	;al contains 5
		call	printStars

		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
	
		call	printName
		pop	eax		;get back address of 5

		mov	al, byte[eax]   ;al contains 5
		call	printStars
		ret

;;; ----------------------------------------------------------------------
;;; printStars
printStars:
		ret
	
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx

		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)

		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		mov	eax, 4
		mov	ebx, 1
		int	0x80
	
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret

	
;;; print message
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, strings	; address of message to print
		mov	edx, 0  	; # of chars to print
		int 	0x80


topDown2.asm


;;; towDown.asm
;;; in this version we expand printName
	
		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"

		section	.text
		global	_start
_start:	


		mov	eax, strings+0 ; eax <- address count+string
		call	printBoxName

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
		mov	al,byte[eax]	;al contains 5
		call	printStars

		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
	
		call	printName
		pop	eax		;get back address of 5

		mov	al, byte[eax]   ;al contains 5
		call	printStars
		ret

;;; ----------------------------------------------------------------------
;;; printStars
printStars:
		ret
	
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx

		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)

		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		mov	eax, 4
		mov	ebx, 1
		int	0x80
	
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret

	
;;; print message
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, strings	; address of message to print
		mov	edx, 0  	; # of chars to print
		int 	0x80


topDown3.asm


;;; towDown.asm
;;; in this version we expand printName
	
		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"

		section	.text
		global	_start
_start:	


		mov	eax, strings+0 ; eax <- address count+string
		call	printBoxName

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
		mov	al,byte[eax]	;al contains 5
		call	printStars

		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
	
		call	printName
		pop	eax		;get back address of 5

		mov	al, byte[eax]   ;al contains 5
		call	printStars
		ret

;;; ----------------------------------------------------------------------
;;; printStars
printStars:
		ret
	
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx

		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)

		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		call	printInt80
	
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret

;;; ----------------------------------------------------------------------
;;; printInt80
;;; gets the address and # of chars to print in ecx and edx.
;;; maintains eax and ebx.
printInt80:	push	eax
		push	ebx
	
		mov	eax, 4
		mov	ebx, 1
		int	0x80
		pop	ebx
		pop	eax
		ret
	
;;; print message
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, strings	; address of message to print
		mov	edx, 0  	; # of chars to print
		int 	0x80


topDown4.asm


;;; towDown.asm
;;; in this version we expand printStars and print a new-line after the name and the line of stars

		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"
oneStar		db	'* '
nl		db	0x0a
	
		section	.text
		global	_start
_start:	


		mov	eax, strings+0 ; eax <- address count+string
		call	printBoxName

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
		mov	al,byte[eax]	;al contains 5
		call	printStars

		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
	
		call	printName
		pop	eax		;get back address of 5

		mov	al, byte[eax]   ;al contains 5
		call	printStars
		ret

;;; ----------------------------------------------------------------------
;;; printStars
;;; gets the number of stars to print in al
;;; maintains all the other registers
printStars:
		push	eax
		push	ecx
		push	edx
	
		mov	ecx, oneStar
		mov	edx, 1
for:		call	printInt80
		dec	al
		jnz	for

		mov	ecx, nl
		call 	printInt80
	
		pop	edx
		pop	ecx
		pop	eax
		ret
	
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx

		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)

		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		call	printInt80

		mov	ecx, nl
		mov	edx, 1
		call	printInt80
	
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret

;;; ----------------------------------------------------------------------
;;; printInt80
;;; gets the address and # of chars to print in ecx and edx.
;;; maintains eax and ebx.
printInt80:	push	eax
		push	ebx
	
		mov	eax, 4
		mov	ebx, 1
		int	0x80
		pop	ebx
		pop	eax
		ret
	
;;; print message
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, strings	; address of message to print
		mov	edx, 0  	; # of chars to print
		int 	0x80


topDown5.asm


;;; towDown.asm
;;; in this version we modify the functions to print extra stars to forma box

		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"
oneSpace	db	' '	
oneStar		db	'*'
nl		db	0x0a
	
		section	.text
		global	_start
_start:	


		mov	eax, strings+0 ; eax <- address count+string
		call	printBoxName

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
		mov	al,byte[eax]	;al contains 5
		call	printStars

		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
	
		call	printName
		pop	eax		;get back address of 5

		mov	al, byte[eax]   ;al contains 5
		call	printStars
		ret

;;; ----------------------------------------------------------------------
;;; printStars
;;; gets the number of stars to print in al
;;; maintains all the other registers
printStars:
		push	eax
		push	ecx
		push	edx

		add	al, 2+2		; add 2 stars in front and back
		mov	ecx, oneStar
		mov	edx, 1 		; print 1 start
for:		call	printInt80
		dec	al
		jnz	for

		mov	ecx, nl
		call 	printInt80
	
		pop	edx
		pop	ecx
		pop	eax
		ret
	
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx

		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
	
		mov	ecx, oneSpace   ; print ' '
		mov	edx, 1
		call	printInt80

		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)

		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		call	printInt80

		mov	ecx, oneSpace 	; print ' '
		mov	edx, 1
		call	printInt80

		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
	
		mov	ecx, nl		; go to the next line
		mov	edx, 1
		call	printInt80
	
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret

;;; ----------------------------------------------------------------------
;;; printInt80
;;; gets the address and # of chars to print in ecx and edx.
;;; maintains eax and ebx.
printInt80:	push	eax
		push	ebx
	
		mov	eax, 4
		mov	ebx, 1
		int	0x80
		pop	ebx
		pop	eax
		ret
	
;;; print message
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, strings	; address of message to print
		mov	edx, 0  	; # of chars to print
		int 	0x80


topDown6.asm


;;; towDown.asm
;;; in this version we create a loop to print all the boxed names.	

		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"
oneSpace	db	' '	
oneStar		db	'*'
nl		db	0x0a
	
		section	.text
		global	_start
_start:	

		mov	ecx, 3
	
		mov	eax, strings+0 ; eax <- address count+string
	
.for:		call	printBoxName

		mov	bl, byte[eax]   ; bl gets # bytes
		and	ebx, 0x000000ff ; extend bl in ebx
		inc	ebx		; add 1 for byte containing #
		add	eax, ebx	; make eax point to next string
		loop	.for

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
	
		mov	al,byte[eax]	;al contains 5
		call	printStars

		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
	
		call	printName
		pop	eax		;get back address of 5
		push	eax
	
		mov	al, byte[eax]   ;al contains 5
		call	printStars

		pop	eax
		ret

;;; ----------------------------------------------------------------------
;;; printStars
;;; gets the number of stars to print in al
;;; maintains all the other registers
printStars:
		push	eax
		push	ecx
		push	edx

		add	al, 2+2		; add 2 stars in front and back
		mov	ecx, oneStar
		mov	edx, 1 		; print 1 start
.for:		call	printInt80
		dec	al
		jnz	.for

		mov	ecx, nl
		call 	printInt80
	
		pop	edx
		pop	ecx
		pop	eax
		ret
	
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx

		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
	
		mov	ecx, oneSpace   ; print ' '
		mov	edx, 1
		call	printInt80

		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)

		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		call	printInt80

		mov	ecx, oneSpace 	; print ' '
		mov	edx, 1
		call	printInt80

		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
	
		mov	ecx, nl		; go to the next line
		mov	edx, 1
		call	printInt80
	
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret

;;; ----------------------------------------------------------------------
;;; printInt80
;;; gets the address and # of chars to print in ecx and edx.
;;; maintains eax and ebx.
printInt80:	push	eax
		push	ebx
	
		mov	eax, 4
		mov	ebx, 1
		int	0x80
		pop	ebx
		pop	eax
		ret
	
;;; print message
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, strings	; address of message to print
		mov	edx, 0  	; # of chars to print
		int 	0x80


topDown7.asm


;;; towDown.asm
;;; in this version we create a loop to print all the boxed names.	

		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"
oneSpace	db	' '	
oneStar		db	'*'
nl		db	0x0a
	
		section	.text
		global	_start
_start:	

		mov	ecx, 3
	
		mov	eax, strings+0 ; eax <- address count+string
	
.for:		call	printBoxName

		mov	bl, byte[eax]   ; bl gets # bytes
		and	ebx, 0x000000ff ; extend bl in ebx
		inc	ebx		; add 1 for byte containing #
		add	eax, ebx	; make eax point to next string
		loop	.for

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	ecx
		push	edx
		push	eax		;eax contains address of 5
	
		mov	al,byte[eax]	;al contains 5
		call	printStars

		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
	
		call	printName
		pop	eax		;get back address of 5
		push	eax
	
		mov	al, byte[eax]   ;al contains 5
		call	printStars

		mov	ecx, nl		;print extra nl char
		mov	edx, 1
		call	printInt80
	
		pop	eax
		pop	edx
		pop	ecx
		ret

;;; ----------------------------------------------------------------------
;;; printStars
;;; gets the number of stars to print in al
;;; maintains all the other registers
printStars:
		push	eax
		push	ecx
		push	edx

		add	al, 2+2		; add 2 stars in front and back
		mov	ecx, oneStar
		mov	edx, 1 		; print 1 start
.for:		call	printInt80
		dec	al
		jnz	.for

		mov	ecx, nl
		call 	printInt80
	
		pop	edx
		pop	ecx
		pop	eax
		ret
	
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx

		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
	
		mov	ecx, oneSpace   ; print ' '
		mov	edx, 1
		call	printInt80

		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)

		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		call	printInt80

		mov	ecx, oneSpace 	; print ' '
		mov	edx, 1
		call	printInt80

		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
	
		mov	ecx, nl		; go to the next line
		mov	edx, 1
		call	printInt80
	
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret

;;; ----------------------------------------------------------------------
;;; printInt80
;;; gets the address and # of chars to print in ecx and edx.
;;; maintains eax and ebx.
printInt80:	push	eax
		push	ebx
	
		mov	eax, 4
		mov	ebx, 1
		int	0x80
		pop	ebx
		pop	eax
		ret
	
;;; print message
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, strings	; address of message to print
		mov	edx, 0  	; # of chars to print
		int 	0x80


topDown.asm


;;; towDown.asm
;;; in this version we expand printName
	
		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"

		section	.text
		global	_start
_start:	


		mov	eax, strings+0 ; eax <- address count+string
		call	printBoxName

;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80

;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
		mov	al,byte[eax]	;al contains 5
		call	printStars

		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
	
		call	printName
		pop	eax		;get back address of 5

		mov	al, byte[eax]   ;al contains 5
		call	printStars
		ret

;;; ----------------------------------------------------------------------
;;; printStars
printStars:
		ret
	
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx

		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)

		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		mov	eax, 4
		mov	ebx, 1
		int	0x80
	
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret

	
;;; print message
		mov	eax, 4		; write
		mov	ebx, 1		; stdout
		mov	ecx, strings	; address of message to print
		mov	edx, 0  	; # of chars to print
		int 	0x80


topDown_v1.asm


;;; towDown.asm
;;; only the main program is expanded here.
 
		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"
 
		section	.text
		global	_start
_start:	
 
 
		mov	eax, strings+0 ; eax <- address count+string
		call	printBoxName
 
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80
 
;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
		mov	al,byte[eax]	;al contains 5
		call	printStars
 
		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
 
		call	printName
		pop	eax		;get back address of 5
 
		mov	al, byte[eax]   ;al contains 5
		call	printStars
		ret
 
;;; ----------------------------------------------------------------------
;;; printStars
printStars:
		ret
 
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		ret


topDown_v2.asm


;;; towDown.asm
;;; in this version we expand printName
 
		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"
 
		section	.text
		global	_start
_start:	
 
 
		mov	eax, strings+0 ; eax <- address count+string
		call	printBoxName
 
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80
 
;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
		mov	al,byte[eax]	;al contains 5
		call	printStars
 
		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
 
		call	printName
		pop	eax		;get back address of 5
 
		mov	al, byte[eax]   ;al contains 5
		call	printStars
		ret
 
;;; ----------------------------------------------------------------------
;;; printStars
printStars:
		ret
 
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx
 
		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)
 
		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		mov	eax, 4
		mov	ebx, 1
		int	0x80
 
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret


topDown_v3.asm


;;; towDown.asm
;;; in this version we  modify printName and add printInt80
 
		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"
 
		section	.text
		global	_start
_start:	
 
 
		mov	eax, strings+0 ; eax <- address count+string
		call	printBoxName
 
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80
 
;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
		mov	al,byte[eax]	;al contains 5
		call	printStars
 
		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
 
		call	printName
		pop	eax		;get back address of 5
 
		mov	al, byte[eax]   ;al contains 5
		call	printStars
		ret
 
;;; ----------------------------------------------------------------------
;;; printStars
printStars:
		ret
 
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx
 
		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)
 
		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		call	printInt80
 
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret
 
;;; ----------------------------------------------------------------------
;;; printInt80
;;; gets the address and # of chars to print in ecx and edx.
;;; maintains eax and ebx.
printInt80:	push	eax
		push	ebx
 
		mov	eax, 4
		mov	ebx, 1
		int	0x80
		pop	ebx
		pop	eax
		ret


topDown_v4.asm


;;; towDown.asm
;;; in this version we expand printStars and print a new-line after the name and the line of stars
 
		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"
oneStar		db	'* '
nl		db	0x0a
 
		section	.text
		global	_start
_start:	
 
 
		mov	eax, strings+0 ; eax <- address count+string
		call	printBoxName
 
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80
 
;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
		mov	al,byte[eax]	;al contains 5
		call	printStars
 
		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
 
		call	printName
		pop	eax		;get back address of 5
 
		mov	al, byte[eax]   ;al contains 5
		call	printStars
		ret
 
;;; ----------------------------------------------------------------------
;;; printStars
;;; gets the number of stars to print in al
;;; maintains all the other registers
printStars:
		push	eax
		push	ecx
		push	edx
 
		mov	ecx, oneStar
		mov	edx, 1
for:		call	printInt80
		dec	al
		jnz	for
 
		mov	ecx, nl
		call 	printInt80
 
		pop	edx
		pop	ecx
		pop	eax
		ret
 
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx
 
		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)
 
		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		call	printInt80
 
		mov	ecx, nl
		mov	edx, 1
		call	printInt80
 
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret
 
;;; ----------------------------------------------------------------------
;;; printInt80
;;; gets the address and # of chars to print in ecx and edx.
;;; maintains eax and ebx.
printInt80:	push	eax
		push	ebx
 
		mov	eax, 4
		mov	ebx, 1
		int	0x80
		pop	ebx
		pop	eax
		ret


topDown_v5.asm


;;; towDown.asm
;;; in this version we modify the functions to print extra stars to form a box
 
		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"
oneSpace	db	' '	
oneStar		db	'*'
nl		db	0x0a
 
		section	.text
		global	_start
_start:	
 
 
		mov	eax, strings+0 ; eax <- address count+string
		call	printBoxName
 
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80
 
;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
		mov	al,byte[eax]	;al contains 5
		call	printStars
 
		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
 
		call	printName
		pop	eax		;get back address of 5
 
		mov	al, byte[eax]   ;al contains 5
		call	printStars
		ret
 
;;; ----------------------------------------------------------------------
;;; printStars
;;; gets the number of stars to print in al
;;; maintains all the other registers
printStars:
		push	eax
		push	ecx
		push	edx
 
		add	al, 2+2		; add 2 stars in front and back
		mov	ecx, oneStar
		mov	edx, 1 		; print 1 start
for:		call	printInt80
		dec	al
		jnz	for
 
		mov	ecx, nl
		call 	printInt80
 
		pop	edx
		pop	ecx
		pop	eax
		ret
 
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx
 
		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
 
		mov	ecx, oneSpace   ; print ' '
		mov	edx, 1
		call	printInt80
 
		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)
 
		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		call	printInt80
 
		mov	ecx, oneSpace 	; print ' '
		mov	edx, 1
		call	printInt80
 
		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
 
		mov	ecx, nl		; go to the next line
		mov	edx, 1
		call	printInt80
 
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret
 
;;; ----------------------------------------------------------------------
;;; printInt80
;;; gets the address and # of chars to print in ecx and edx.
;;; maintains eax and ebx.
printInt80:	push	eax
		push	ebx
 
		mov	eax, 4
		mov	ebx, 1
		int	0x80
		pop	ebx
		pop	eax
		ret


topDown_v6.asm


;;; towDown.asm
;;; in this version we create a loop to print all the boxed names.	
;;; we also change the "for" labels into ".for" (local labels)
 
		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"
oneSpace	db	' '	
oneStar		db	'*'
nl		db	0x0a
 
		section	.text
		global	_start
_start:	
 
		mov	ecx, 3
 
		mov	eax, strings+0 ; eax <- address count+string
 
.for:		call	printBoxName
 
		mov	bl, byte[eax]   ; bl gets # bytes
		and	ebx, 0x000000ff ; extend bl in ebx
		inc	ebx		; add 1 for byte containing #
		add	eax, ebx	; make eax point to next string
		loop	.for
 
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80
 
;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	eax		;eax contains address of 5
 
		mov	al,byte[eax]	;al contains 5
		call	printStars
 
		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
 
		call	printName
		pop	eax		;get back address of 5
		push	eax
 
		mov	al, byte[eax]   ;al contains 5
		call	printStars
 
		pop	eax
		ret
 
;;; ----------------------------------------------------------------------
;;; printStars
;;; gets the number of stars to print in al
;;; maintains all the other registers
printStars:
		push	eax
		push	ecx
		push	edx
 
		add	al, 2+2		; add 2 stars in front and back
		mov	ecx, oneStar
		mov	edx, 1 		; print 1 start
.for:		call	printInt80
		dec	al
		jnz	.for
 
		mov	ecx, nl
		call 	printInt80
 
		pop	edx
		pop	ecx
		pop	eax
		ret
 
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx
 
		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
 
		mov	ecx, oneSpace   ; print ' '
		mov	edx, 1
		call	printInt80
 
		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)
 
		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		call	printInt80
 
		mov	ecx, oneSpace 	; print ' '
		mov	edx, 1
		call	printInt80
 
		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
 
		mov	ecx, nl		; go to the next line
		mov	edx, 1
		call	printInt80
 
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret
 
;;; ----------------------------------------------------------------------
;;; printInt80
;;; gets the address and # of chars to print in ecx and edx.
;;; maintains eax and ebx.
printInt80:	push	eax
		push	ebx
 
		mov	eax, 4
		mov	ebx, 1
		int	0x80
		pop	ebx
		pop	eax
		ret


topDown_v7.asm


;;; towDown.asm
;;; in this version we clean up the code.
 
		section	.data
strings		db	5, "Hello"
		db	6, "Sharon"
		db	7, "Pamela!"
oneSpace	db	' '	
oneStar		db	'*'
nl		db	0x0a
 
		section	.text
		global	_start
_start:	
 
		mov	ecx, 3
 
		mov	eax, strings+0 ; eax <- address count+string
 
.for:		call	printBoxName
 
		mov	bl, byte[eax]   ; bl gets # bytes
		and	ebx, 0x000000ff ; extend bl in ebx
		inc	ebx		; add 1 for byte containing #
		add	eax, ebx	; make eax point to next string
		loop	.for
 
;;; exit
		mov	ebx, 0
		mov	eax, 1
		int	0x80
 
;;; ----------------------------------------------------------------------
;;; printBoxName
printBoxName:	push	ecx
		push	edx
		push	eax		;eax contains address of 5
 
		mov	al,byte[eax]	;al contains 5
		call	printStars
 
		pop	eax		;address of 5
		push	eax		;put the address of 5 back in stack
 
		call	printName
		pop	eax		;get back address of 5
		push	eax
 
		mov	al, byte[eax]   ;al contains 5
		call	printStars
 
		mov	ecx, nl		;print extra nl char
		mov	edx, 1
		call	printInt80
 
		pop	eax
		pop	edx
		pop	ecx
		ret
 
;;; ----------------------------------------------------------------------
;;; printStars
;;; gets the number of stars to print in al
;;; maintains all the other registers
printStars:
		push	eax
		push	ecx
		push	edx
 
		add	al, 2+2		; add 2 stars in front and back
		mov	ecx, oneStar
		mov	edx, 1 		; print 1 start
.for:		call	printInt80
		dec	al
		jnz	.for
 
		mov	ecx, nl
		call 	printInt80
 
		pop	edx
		pop	ecx
		pop	eax
		ret
 
;;; ----------------------------------------------------------------------
;;; printName
;;; gets the address of the byte containing the number of chars to print
;;; in eax.  address of string is at eax+1
;;; Does not modify any registers.
printName:
		push	eax		; save registers
		push	ebx
		push	ecx
		push	edx
 
		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
 
		mov	ecx, oneSpace   ; print ' '
		mov	edx, 1
		call	printInt80
 
		mov	dl, byte[eax] 	;get # chars in dl
		and	edx,0x000000ff  ;clear upper part of edx (not dl)
 
		inc	eax		;eax points to string
		mov	ecx, eax	;ecx points to string
		call	printInt80
 
		mov	ecx, oneSpace 	; print ' '
		mov	edx, 1
		call	printInt80
 
		mov	ecx, oneStar 	; print '*'
		mov	edx, 1
		call	printInt80
 
		mov	ecx, nl		; go to the next line
		mov	edx, 1
		call	printInt80
 
		pop	edx		;restore the registers
		pop	ecx
		pop	ebx
		pop	eax
		ret
 
;;; ----------------------------------------------------------------------
;;; printInt80
;;; gets the address and # of chars to print in ecx and edx.
;;; maintains eax and ebx.
printInt80:	push	eax
		push	ebx
 
		mov	eax, 4
		mov	ebx, 1
		int	0x80
		pop	ebx
		pop	eax
		ret


C/C++/Java Files

Demo1.java


public class Demo1 {
    final static byte START  = 0x01;
    final static byte PHASE1 = 0x02;
    final static byte PHASE2 = 0x04;
    final static byte PHASE3 = 0x08;
    final static byte DONE   = 0x10;
    
    /**
     * @param args
     */
    public static void main(String[] args) {
	byte status = START;
	System.out.println( "Status = " + toBinary8( status ) );
	
	for ( int i = 0; i< 100; i++ ) {
	    if ( Math.random() < 0.1 ) status = (byte) (status | PHASE1);
	    else if ( Math.random() < 0.1 ) status = (byte) (status ^ PHASE1);
	    else if ( Math.random() < 0.1 ) status = (byte) (status ^ PHASE2);
	    else if ( Math.random() < 0.1 ) status = (byte) (status ^ PHASE3);
	    else if ( Math.random() < 0.1 ) status = (byte) (status ^ DONE);
	    System.out.println( "Status = " + toBinary8( status ) );
	    if ( (status & DONE) != 0) 
		break;
	}	
    }
 
    private static String toBinary8( byte x ) {
	return  String.format( "%8s", Integer.toBinaryString(x) ).replace(' ', '0');
    }
}


driver.c


#include <stdio.h>

extern int asm_main( void );

int main() {
  asm_main();
}


FloatingPointStrange2.java


// taken from http://www.lahey.com/float.htm

class FloatingPointStrange2 {
   
    
    public static void main( String args[] ) {
	float x, y;
	int c;
	x = 8.6f;
	y = 1.4f;
	c = (int) (x + y);
	
	System.out.println( String.format( "%1.2f + %1.2f = %1.2f = %d", x, y, x+y, c ) );
	System.out.println( String.format( "%1.40f + %1.40f = %1.40f = %d", x, y, x+y, c ) );

	x = 8.7f;
	y = 1.3f;
	c = (int) (x + y);

	System.out.println( String.format( "%1.2f + %1.2f = %1.2f = %d", x, y, x+y, c ) );
	System.out.println( String.format( "%1.40f + %1.40f = %1.40f = %d", x, y, x+y, c ) );
			    
    }
}


FloatingPointStrange3.cpp


// taken from http://www.lahey.com/float.htm
#include <iostream>
#include <stdio.h>
using namespace std;

int main( int argc, char *argv[] ) {
  double x = 77777.0;
  double y = 7.0;
  double y1 = 1.0 / y;    // 1/7
  double z = x / y;       // 77777 / 7 = 11111
  double z1 = x * y1;     // 77777 * 1/7 = 11111
  
  if ( z != z1 ) {
    cout << z << " != " << z1 << endl;
    printf( "%1.20f != %1.20f\n", z, z1 );
  }
  else {
    cout << z << " == " << z1 << endl;
    printf( "%1.20f == %1.20f\n", z, z1 );
  }

  return 0;
}


FloatingPointStrange3.java


// taken from http://www.lahey.com/float.htm

class DoubleingPointStrange3 {
   
    
    public static void main( String args[] ) {
	double x, y, y1, z, z1;

	x = 77777.0;
	y = 7.0;
	y1 = 1.0 / y;    // 1/7
	z = x / y;       // 77777 / 7 = 10000
	z1 = x * y1;     // 77777 * 1/7 = 10000
	
	if ( z != z1 ) {
	    System.out.println( String.format( "%1.3f != %1.3f", z, z1 ) );
	    System.out.println( String.format( "%1.30f != %1.30f", z, z1 ) );
	}
	else {
	    System.out.println( String.format( "%1.3f == %1.3f", z, z1 ) );
	    System.out.println( String.format( "%1.30f == %1.30f", z, z1 ) );
	}
			    
    }
}


FloatingPointStrange.cpp


// taken from http://www.lahey.com/float.htm
#include <iostream>
using namespace std;

int main( int argc, char *argv[] ) {
  float x = 8.7;
  float y = 1.3;
  int   c = (int) (x+y);

  cout <<  x << " + " << y << " = " << x+y << "  c = " << c << endl;

  return 0;
}


FloatingPointStrange.java


// taken from http://www.lahey.com/float.htm

class FloatingPointStrange {
   
    
    public static void main( String args[] ) {
	float x = 0.1f;

	if ( x * 10.0f != 1.0f ) 
	    System.out.println( x + " * 10.0 != 1.0 " );
	else
	    System.out.println( x + " * 10.0 == 1.0 " );
    }
}


MultBy3.java


// MultBy3.java
// D. Thiebaut
// A simple program to illustrates what happens when an overflow occurs
// in an int variable.
//
// To compile and run:
//  javac MultBy3.java
//  java MultBy3
//
public class MultBy3 {

    public static void main( String[] args ) {
	long a = 2;
	for ( int i=0; i<70; i++ ) {
	    //System.out.println( a );
	    System.out.println( String.format( "%20d %16s %64s", a , Long.toHexString(a), Long.toBinaryString( a ) ) );
	    //System.out.println( String.format( "%12d %8s %32s", a , Integer.toHexString(a), Integer.toBinaryString( a ) ) );
	    a *= 3;
	}
    }
}


ShiftRight.java


// ShiftRight.java
// D. Thiebaut
// To compile and run:
//       javac ShiftRight.java
//       java ShiftRight
 
public class ShiftRight {
 
    public static void main(String[] args) {
	for ( int i=-10; i<10; i++ ) {
	    int a = i >> 2;
	    int b = i / 2;
	    System.out.println( "i = " + i + " \ti >> 1  = " + a + " \ti / 2  = " + b );
	}
    }
}


Python Files

generateTableLookupHexadecimal.py


s = "table\tdb\t"
for i in range(256):
    #print "%d %02X" % (i, i ) 
    if ( i!=0 and i%8==0 ):
        s += "\n\tdb\t"
    else:
        if ( i!=0 ):
            s += ", "
    s += '"%02X"' % i

print s




hanoi2.py


# hanoi.py  (Python V 2.7)
# D. Thiebaut
# implements the game of hanoi in python.
# uses recursion.
#
# to run, type 
#        python hanoi.py 
# at the command line
N = 0

def indent( n ):
    return (N+1-n)*'|    '

def moveDisk( source, dest, extra, n ):
    print "%smoveDisk( %s, %s, %s, %d)" % ( indent(n), source, dest, extra, n )
    if n==1:
        print  indent(n-1) + ( "%s --> %s" % ( source, dest ) )
        return
 
    # more than 1 disk...
    moveDisk( source, extra, dest, n-1)
    print indent(n-1) + ( "%s --> %s" % ( source, dest ) )
    moveDisk( extra, dest, source, n-1)
 
def main():
    global N
    while True:
        N = input( "\n\n# of disks? " )
        moveDisk( "A", "B", "C", N )
 
main()




hanoi3.py


# hanoi3.py  (Python V 2.7)
# D. Thiebaut
# implements the game of hanoi in python.
# uses recursion and some of the tail recursion
# trimmed at N==2
#
# to run, type 
#        python hanoi.py 
# at the command line

count = 0

def moveDisk( source, dest, extra, n ):
    global count
    if n>2:
        # more than 1 disk...
        moveDisk( source, extra, dest, n-1)
        #print "move disk from %s to %s" % ( source, dest )
        count += 1
        moveDisk( extra, dest, source, n-1)
    elif n==2:
        #print "move disk from %s to %s" % ( source, extra )
        #print "move disk from %s to %s" % ( source, dest )
        #print "move disk from %s to %s" % ( extra, dest )
        count += 3
    else:
        #print "move disk from %s to %s" % ( source, dest )
        count += 1

def main():
    global count
    while True:
        count = 0
        n = input( "# of disks? " )
        moveDisk( "A", "B", "C", n )
        print count, "moves..."

main()




hanoi.py


# hanoi.py  (Python V 2.7)
# D. Thiebaut
# implements the game of hanoi in python.
# uses recursion.
#
# to run, type 
#        python hanoi.py 
# at the command line
 
def moveDisk( source, dest, extra, n ):
    if n==1:
        print "move disk from %s to %s" % ( source, dest )
        return
 
    # more than 1 disk...
    moveDisk( source, extra, dest, n-1)
    print "move disk from %s to %s" % ( source, dest )
    moveDisk( extra, dest, source, n-1)
 
def main():
    while True:
        n = input( "# of disks? " )
        moveDisk( "A", "B", "C", n )
 
main()




multBy3.py


# multBy3.py
# D. Thiebaut
# A simple program showing how Python deals with
# integer overflow.

a = 2

for i in range( 700 ):
    print a
    a = a * 3




Script to Generate This List

#!/bin/bash

echo "=Listings from ~231a/handout="
echo "==Asm Files=="
for file in `ls ~/handout/*.asm ~/handout/*.inc` ; do
#echo $i
echo "===$(basename $file)==="
echo "<br /><source lang=\"asm\">"
cat $file
echo "</source><br /><br />"
done