CSC231 Homework 9 Solutions

From dftwiki3
Jump to: navigation, search

--D. Thiebaut 11:55, 20 November 2012 (EST)


Programming


;;; hw9.asm
;;; Naomi Long
;;; 231a-ad
;;;
;;; Plays game of life 20 times with 1D array of 70 orgs. Displays
;;; dead organisms as '.' and live ones as 'o'. First and last orgs
;;; in org array represent outside boundaries and are always dead.
;;; 
;;; Takes initial org array and updates it based on 3 rules of life.
;;; 1. If two dead neighbors, org dies. 2. If two live neighbors,
;;; org dies. 3. If one dead and one live neighbor, lives.
;;;
;;; Sample output cut down for space, sandwiched between two prompts:
;;; [231a-ad@grendel ~/hw9]$ ./hw9
;;; o.o....oo....o......o.........
;;; ...o..oooo..o.o....o.o........
;;; ..o.ooo..ooo...o..o...o.......
;;; .o..o.oooo.oo.o.oo.o.o.o......
;;; o.oo..o..o.oo...oo......o.....
;;; [231a-ad@grendel ~/hw9]$
;;;
;;; To run:
;;; nasm -f elf -F stabs hw9.asm ; ld -melf_i386 -o hw9 hw9.o ; ./hw9
	
;;;  -------------------------
;;;  data segment
;;;  -------------------------

	section .data
	fate	db	0,1,0			; fate table for future org statuses
	orgs	db	0,1,0,1,0,0,0,0,1,1 	; initial org statues, first and
		db      0,0,0,0,1,0,0,0,0,0 	; last orgs count as boundaries
		db      0,1,0,0,0,0,0,0,0,0
		db      0,0,0,1,0,1,0,0,0,1
		db      0,0,0,0,0,0,0,0,0,1
		db      0,1,0,0,0,1,0,0,0,0
		db      1,0,1,0,0,1,0,0,1,0
	numOrgs equ     $-orgs-2 		; number of orgs mins boundaries
	temp	db      0,0,0,0,0,0,0,0,0,0 	; stores temp new status for updating
		db      0,0,0,0,0,0,0,0,0,0 
		db      0,0,0,0,0,0,0,0,0,0
        	db      0,0,0,0,0,0,0,0,0,0
        	db      0,0,0,0,0,0,0,0,0,0
        	db      0,0,0,0,0,0,0,0,0,0
        	db      0,0,0,0,0,0,0,0,0,0
	chars	db	".","o"			; chars representing dead and live orgs
	newline	db	10
	
;;;  -------------------------
;;;  code area
;;;  -------------------------

	section .text
	global  _start:
_start:
	push	dword numOrgs
	push	dword orgs
	push	dword chars
	call	printStatus		; print initial arrangement of orgs

	push	dword newline
	call	printNewLine		; print new line

	mov	ecx, 20			; play game of life 20 times
.playGame:
	push	dword numOrgs	
	push	dword orgs
	push	dword temp
	call	update			; changes orgs by conway's rules
	
	push    dword numOrgs
	push    dword orgs
	push    dword chars
	call	printStatus		; print current arrangement of orgs

	push	dword newline
	call	printNewLine		; print new line

	loop	.playGame		
	
;;; exit
	mov	ebx, 0
	mov	eax, 1
	int	0x80

;;; ---------------------------------------------------
;;; update
;;; Updates org statuses based on rules of game. Doesn't
;;; iterate over first and last orgs, which represent
;;; outside boundaries and are always dead. Takes 3
;;; dword parameters: number of orgs in array, addrs
;;; of org array, and addrs of temp array. Doesn't
;;; modify any registers.
;;; ---------------------------------------------------
update:
	push	ebp			; save caller's ebp
	mov	ebp, esp
	pushad

	mov	eax, 0			; clear eax
	mov	ecx, dword[ebp+16]	; update all orgs

	mov	ebx, dword[ebp+12]	; ebx = addrs of first org
	mov	edx, dword[ebp+8]	; edx = addrs of first temp storage cell
.for:
	inc	ebx			; ebx points to next org
	inc	edx			; edx points to next temp storage cell
	
	sub	esp, 4	   		; make space for return value
	push	ebx			; push addrs of current org
	call	getFate			; get new status of org
	pop	eax			; eax = returned new org status
	
	mov	byte[edx], al		; stores new status in temp storage
					; to avoid updating based on new statuses
	loop	.for

	push	dword[ebp+16]
	push	dword[ebp+12]
	push	dword[ebp+8]
	call	moveTempToOrgs		; moves updated temp statuses to org array

	popad
	pop	ebp			; restore caller's ebp
	ret	3*4			; destroy 3 dword stack frame

;;; ---------------------------------------------------
;;; getFate
;;; Takes a stack frame holding dword space for return
;;; value and dword addrs of next org. Gets fate of
;;; passed org and stores its new status in return
;;; value. Then destroys stack frame except return value.
;;; Doesn't modify any registers.
;;; ---------------------------------------------------
getFate:	
	push	ebp			; save caller's ebp
	mov	ebp, esp		; ebp points to current stack position
	push	eax			; save eax	
	push	ebx			; save ebx

	mov	ebx, 0			; clear ebx
	
	mov	eax, dword[ebp+8] 	; eax = addrs of current org
	mov	bl, byte[eax-1]		; bl = status of org to left
	add	bl, byte[eax+1]		; bl = left org status + right org status
	mov	bl, byte[fate+ebx]	; get new status according to rules
	mov	dword[ebp+12], ebx	; store return value of new status in stack
	
	pop	ebx			; restore ebx
	pop	eax			; restore eax
	pop	ebp			; restore caller's ebp
	
	ret 	1*4			; destorys allocated stack frame but not return value

;;; ---------------------------------------------------
;;; moveTempToOrgs
;;; Moves statuses in temp array to orgs. Doesn't
;;; modify registers. Takes 3 dword parameters:
;;; number of orgs in arrays, addrs of orgs array, and
;;; addrs of temp array.
;;; ---------------------------------------------------
moveTempToOrgs:
	push	ebp			; save caller's ebp
	mov	ebp, esp
	pushad
	
	mov	ecx, dword[ebp+16]	; loop over all orgs
	mov	ebx, dword[ebp+12]	; ebx = orgs addrs
	mov	edx, dword[ebp+8]	; edx = temp addrs
	mov	eax, 0			; clear eax
.for:
	inc	ebx
	inc	edx
	
	mov	al, byte[edx] 		; eax = current temp status
	mov	byte[ebx], al		; stores eax in current org

	loop	.for

	popad
	pop	ebp			; restore caller's ebp
	ret	3*4			; destroy 3 dword stack frame
	
;;; ---------------------------------------------------
;;; printStatus
;;; Prints orgs as chars "." and "o", if alive or dead,
;;; respectively. Doesn't print boundaries (first and
;;; last members. Takes 3 dword parameters: number of
;;; orgs to print, addrs of org array, and addrs of
;;; representation chars. Destroys stack frame when
;;; done. Doesn't modify registers.
;;; ---------------------------------------------------
printStatus:
	push 	ebp			; saves caller's ebp
	mov	ebp, esp
	pushad

	mov	ecx, dword[ebp+16]	; ecx = num of orgs, will print all orgs in array
	mov	eax, dword[ebp+12]	; eax = addrs of orgs
	mov	ebx, dword[ebp+8]	; ebx = addrs of chars
.for:
	push	ecx		   	; save current iteration
	mov	ecx, 0			; clear ecx

	inc	eax		   	; eax points to current org
	mov	cl, byte[eax] 		; get status of org, 0 or 1
	add	ecx, ebx		; gets representation char, '.' or 'o'

	push	eax			; save current addrs of orgs
	push	ebx			; save chars addrs
	mov	eax, 4
	mov	ebx, 1
	mov	edx, 1
	int	0x80			; print current org status
	pop	ebx			; restore chars addrs
	pop	eax			; restore current addrs of orgs

 	pop	ecx			; get current iteration
	loop	.for			; print all orgs in array
	
	popad	
	pop	ebp			; restores caller's ebp
	ret	3*4			; destroys 3 dword stack frame

;;; ---------------------------------------------------
;;; printNewLine
;;; Prints a new line. Takes addrs of newline character
;;; as paramater pushed in stack. Destroys stack frame
;;; afterwards. Doesn't modify registers.
;;; ---------------------------------------------------
printNewLine:
	push	ebp			; save caller's ebp
	mov	ebp, esp
	pushad

	mov	eax, 4
	mov	ebx, 1
	mov	ecx, dword[ebp+8] 	; points to new line char on stack
	mov	edx, 1
	int	0x80

	popad
	pop	ebp			; restore caller's ebp
	ret	1*4