Difference between revisions of "CSC231 Homework Solutions 2017"
(→hw5_1.asm) |
(→hw5_2.sh) |
||
Line 449: | Line 449: | ||
done | done | ||
</source> | </source> | ||
+ | <br /> | ||
+ | ::<source lang="asm"> | ||
+ | 231b@aurora ~/hw/hw6 $ cat GameOfLife.asm | ||
+ | ;;; ; GameOfLife.asm | ||
+ | ;;; ; Authors: D. Thiebaut and CSC231 Class | ||
+ | ;;; ; | ||
+ | ;;; ; Implements a 1-dimensional version of | ||
+ | ;;; ; Conway's Game of life. | ||
+ | ;;; ; Note that because we do not "know" yet | ||
+ | ;;; ; how to test or to use functions, the code | ||
+ | ;;; ; is not as efficient as it could be. | ||
+ | ;;; ; | ||
+ | ;;; ; to assemble and run: | ||
+ | ;;; ; | ||
+ | ;;; ; nasm -f elf -F stabs GameOfLife.asm | ||
+ | ;;; ; ld -melf_i386 -o GameOfLife GameOfLife.o | ||
+ | ;;; ; ./GameOfLife | ||
+ | ;;; ; ------------------------------------------------------------------- | ||
+ | |||
+ | |||
+ | ;;; ------------------------------------------------------------ | ||
+ | ;;; data areas | ||
+ | ;;; ------------------------------------------------------------ | ||
+ | |||
+ | section .data | ||
+ | ;;; the current dish with its cells. We use 0 and 1 to | ||
+ | ;;; indicate dead and live cells, respectively. | ||
+ | %include "dishArray.inc" | ||
+ | |||
+ | ;;; the new generation of cells. That's the "future" of the | ||
+ | ;;; cells in the dish. We make it the same size as dish, and | ||
+ | ;;; fill it with N dead cells. | ||
+ | |||
+ | newGen times N db 0 | ||
+ | |||
+ | ;;; dishP is a string that will contain ' ' or '!' for | ||
+ | ;;; each 0 or 1 in dish. | ||
+ | dishP times N db ' ' | ||
+ | db 10 ; add a \n at the end | ||
+ | ; of dishP | ||
+ | |||
+ | generation dd 0 ; save ecx from for generation loop | ||
+ | i dd 0 ; used by for loops | ||
+ | |||
+ | ;;; ------------------------------------------------------------ | ||
+ | ;;; code area | ||
+ | ;;; ------------------------------------------------------------ | ||
+ | |||
+ | section .text | ||
+ | global _start | ||
+ | |||
+ | _start: | ||
+ | main: | ||
+ | ;;; ------------------------------------------------------------- | ||
+ | ;;; print( dish ) | ||
+ | ;; first we copy dish into dishP and at the same | ||
+ | ;; time replace 0 by ' ' and 1 by '!' | ||
+ | |||
+ | ;;; for i in range( N ): | ||
+ | mov esi, dish | ||
+ | mov edi, dishP | ||
+ | |||
+ | mov dword[i], 0 | ||
+ | forPrint: cmp dword[i], N | ||
+ | jge forPrintEnd | ||
+ | |||
+ | mov al, byte[esi] | ||
+ | add al, ' ' ;0 becomes ' ', 1 becomes '!' | ||
+ | mov byte[edi], al | ||
+ | inc esi ;esi points to next byte in dish | ||
+ | inc edi ;edi points to next byte in dispP | ||
+ | |||
+ | ;; i++, loop back | ||
+ | inc dword[i] | ||
+ | jmp forPrint | ||
+ | forPrintEnd: | ||
+ | |||
+ | ;; print dishP as a string. | ||
+ | mov eax, 4 ;prints dishP to screen | ||
+ | mov ebx, 1 | ||
+ | mov ecx, dishP ;dishP address | ||
+ | mov edx, N+1 ;+1 to include the \n | ||
+ | int 0x80 | ||
+ | |||
+ | |||
+ | ;;; ----------------------------------------------------------- | ||
+ | ;;; for generation in range( maxGen ): | ||
+ | |||
+ | mov dword[generation], 0 | ||
+ | |||
+ | |||
+ | forGen: mov eax, dword[generation] | ||
+ | cmp eax, dword[maxGen] | ||
+ | jge forGenEnd | ||
+ | |||
+ | |||
+ | ;;; ----------------------------------------------------------- | ||
+ | ;;; newGen = life( dish, N ) | ||
+ | ;;; newGen[0] = 0 | ||
+ | ;;; newGen[N-1] = 0 | ||
+ | |||
+ | mov byte[newGen], 0 | ||
+ | mov byte[newGen+N-1], 0 | ||
+ | |||
+ | ;;; ----------------------------------------------------------- | ||
+ | ;;; for i in range( 0, N ): | ||
+ | |||
+ | mov esi, dish | ||
+ | mov edi, newGen | ||
+ | |||
+ | mov dword[i], 0 | ||
+ | |||
+ | forLife: cmp dword[i], N | ||
+ | jge forLifeEnd | ||
+ | |||
+ | ;;; ----------------------------------------------------------- | ||
+ | ;;; fate = dish[i-1] ^ dish[i+1] | ||
+ | ;;; newGen[i] = fate | ||
+ | mov al, byte[esi-1] | ||
+ | xor al, byte[esi+1] | ||
+ | mov byte[edi], al | ||
+ | inc esi | ||
+ | inc edi | ||
+ | |||
+ | inc dword[i] | ||
+ | jmp forLife | ||
+ | forLifeEnd: | ||
+ | |||
+ | ;;; ----------------------------------------------------------- | ||
+ | ;;; dish = newGen | ||
+ | |||
+ | mov dword[i],0 | ||
+ | mov esi, newGen | ||
+ | mov edi, dish | ||
+ | |||
+ | forMove: cmp dword[i], N | ||
+ | jge forMoveEnd | ||
+ | |||
+ | mov al, byte[esi] ;copy newGen[i] to dish[i] | ||
+ | mov byte[edi], al | ||
+ | inc esi | ||
+ | inc edi | ||
+ | |||
+ | inc dword[i] | ||
+ | loop forMove | ||
+ | forMoveEnd: | ||
+ | ;;; ------------------------------------------------------------- | ||
+ | ;;; print( dish ) | ||
+ | ;; first we copy dish into dishP and at the same | ||
+ | ;; time replace 0 by ' ' and 1 by '!' | ||
+ | |||
+ | ;;; for i in range( N ): | ||
+ | mov esi, dish | ||
+ | mov edi, dishP | ||
+ | |||
+ | mov dword[i], 0 | ||
+ | forPrint2: cmp dword[i], N | ||
+ | jge forPrintEnd2 | ||
+ | |||
+ | mov al, byte[esi] | ||
+ | add al, ' ' ;0 becomes ' ', 1 becomes '!' | ||
+ | mov byte[edi], al | ||
+ | inc esi ;esi points to next byte in dish | ||
+ | inc edi ;edi points to next byte in dispP | ||
+ | inc dword[i] | ||
+ | jmp forPrint2 | ||
+ | forPrintEnd2: | ||
+ | |||
+ | ;; print dishP as a string. | ||
+ | mov eax, 4 ;prints dishP to screen | ||
+ | mov ebx, 1 | ||
+ | mov ecx, dishP ;dishP address | ||
+ | mov edx, N+1 ;+1 to include the \n | ||
+ | int 0x80 | ||
+ | |||
+ | ;;; ready to loop back to forGen | ||
+ | inc dword[generation] | ||
+ | jmp forGen | ||
+ | forGenEnd: | ||
+ | |||
+ | ;;; exit() | ||
+ | |||
+ | exit: mov eax,1 | ||
+ | mov ebx,0 | ||
+ | int 0x80 ; final system call | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | <br /> |
Revision as of 17:29, 22 April 2017
--D. Thiebaut (talk) 17:57, 22 April 2017 (EDT)
Problem 1
;;; mystery.asm ;;; D. Thiebaut ;;; ;;; To assemble, link, and run: ;;; nasm -f elf mystery.asm ;;; ld -melf_i386 -o mystery mystery.o ;;; ./mystery ;;; section .data Hello db "Hello there!", 10, 10 HelloLen equ $-Hello section .text global _start _start: ;;; print Hello and a space after it mov eax, 4 ; write mov ebx, 1 ; stdout mov ecx, Hello ; address of message to print mov edx, 6 ; print only 6 chars int 0x80 ;;; print ! and two line feed chars mov eax, 4 ; write mov ebx, 1 ; stdout mov ecx, Hello+11 ; address of ! char mov edx, 3 ; print only 3 chars int 0x80 ;;; exit mov ebx, 0 mov eax, 1 int 0x80
hw1.asm
;;; hw1.asm ;;; D. Thiebaut ;;; ;;; To assemble, link, and run: ;;; nasm -f elf hw1.asm ;;; ld -melf_i386 -o hw1 hw1.o ;;; ./hw1 ;;; section .data msg db " CSC231 Assembly " linefeed db 10 dashline db "------------------" lineLen equ $-dashline section .text global _start _start: ;;; print message mov eax, 4 ; write mov ebx, 1 ; stdout mov ecx, dashline ; address of message to print mov edx, lineLen ; # of chars to print int 0x80 mov eax, 4 ; write mov ebx, 1 ; stdout mov ecx, dashline ; address of message to print mov edx, lineLen ; # of chars to print int 0x80 mov eax, 4 ;print line-feed mov ebx, 1 mov ecx, linefeed mov edx, 1 int 0x80 mov eax, 4 ; write ---- mov ebx, 1 ; stdout mov ecx, dashline ; address of message to print mov edx, 9 ; # of chars to print int 0x80 mov eax, 4 ; write message mov ebx, 1 ; stdout mov ecx, msg ; address of message to print mov edx, lineLen ; # of chars to print int 0x80 mov eax, 4 ; write ---- mov ebx, 1 ; stdout mov ecx, dashline ; address of message to print mov edx, 9 ; # of chars to print int 0x80 mov eax, 4 ;print line-feed mov ebx, 1 mov ecx, linefeed mov edx, 1 int 0x80 mov eax, 4 ; write mov ebx, 1 ; stdout mov ecx, dashline ; address of message to print mov edx, lineLen ; # of chars to print int 0x80 mov eax, 4 ; write mov ebx, 1 ; stdout mov ecx, dashline ; address of message to print mov edx, lineLen ; # of chars to print int 0x80 mov eax, 4 ;print line-feed mov ebx, 1 mov ecx, linefeed mov edx, 1 int 0x80 ;;; exit mov ebx, 0 mov eax, 1 int 0x80
hw2.asm
;;; ; ; hw2sol.asm ;;; ; ; D. Thiebaut ;;; ; ; ;;; ; ; extern _printDec extern _printString extern _println extern _getInput section .data prompt db "> " promptLen equ $-prompt ansStr db "ans = " ansStrLen equ $-ansStr a dd 0 b dd 0 c dd 0 ans dd 0 section .text global _start _start: ;; display prompt mov ecx, prompt mov edx, promptLen call _printString ;; get a call _getInput mov dword[a], eax ;; display prompt mov ecx, prompt mov edx, promptLen call _printString ;; get b call _getInput mov dword[b], eax ;; display prompt mov ecx, prompt mov edx, promptLen call _printString ;; get c call _getInput mov dword[c], eax ;; ----------------------------------- ;; computation: ans = 2*(a-b) + 3*c ;; ----------------------------------- ; your code will go here... ;; ----------------------------------- ;; display "ans =" ;; ----------------------------------- mov ecx, ansStr mov edx, ansStrLen call _printString ;; ----------------------------------- ;; display ans variable ;; ----------------------------------- mov eax, dword[ans] call _printDec call _println call _println ;;; exit mov ebx, 0 mov eax, 1 int 0x80
Teller.asm
;;; ; teller.asm ;;; ; D. Thiebaut ;;; ; ;;; ; Demo of a teller machine program. ;;; ; To assemble, link, and run: ;;; ; nasm -f elf teller.asm ;;; ; ld -melf_i386 -o teller teller.o 231Lib.o ;;; ; ./teller ;;; ; ;;; extern functions that will be linked to this program ;;; ; contained in 231Lib.asm extern _printDec extern _printString extern _println extern _getInput ;;; ------------------------------------------------------ ;;; DATA SECTION ;;; ------------------------------------------------------ section .data amount dd 139 no20s dd 0 no10s dd 0 no5s dd 0 no1s dd 0 msg db "amount? " MSGLEN equ $-msg ;;; ------------------------------------------------------ ;;; CODE SECTION ;;; ------------------------------------------------------ section .text global _start _start: ;;; get amount from the user mov ecx, msg mov edx, MSGLEN call _printString call _getInput mov dword[amount], eax call _println ;;; Break down amount in 20s, 10s, 5s, and 1s mov eax, dword[amount] mov edx, 0 mov ebx, 20 mov eax, dword[amount] call break mov dword[no20s], eax mov ebx, 10 mov eax, dword[amount] call break mov dword[no10s], eax mov ebx, 5 mov eax, dword[amount] call break mov dword[no5s], eax mov eax, dword[amount] mov dword[no1s], eax mov eax, dword[no20s] call _printDec call _println mov eax, dword[no10s] call _printDec call _println mov eax, dword[no5s] call _printDec call _println mov eax, dword[no1s] call _printDec call _println ;;; exit mov ebx, 0 mov eax, 1 int 0x80 ;;; sum: gets 2 ints in eax and ebx and returns the sum in ;;; eax. sum: add eax, ebx, ret ;;; break: gets amount in eax, divider in ebx, divides, ;;; and puts remainder in [amount] and quotient in eax break: mov edx, 0 div ebx mov dword[amount], edx ret
hw5_1.asm
;;; ; hw5_1.asm ;;; ; D. Thiebaut ;;; ; ;;; ; Prints 10 lines of Pascal triangle. ;;; ; ;;; ; to assemble and run: ;;; ; ;;; ; nasm -f elf -F stabs hw5_1.asm ;;; ; ld -melf_i386 -o hw5_1 hw5_1.o ;;; ; ./hw5_1 ;;; ; ------------------------------------------------------------------- extern _printString extern _getInput extern _println ;;; ------------------------------------------------------------ ;;; data areas ;;; ------------------------------------------------------------ section .data prompt db "> " stars db "******************************************" N dd 0 saveECX dd 0 ;;; ------------------------------------------------------------ ;;; code area ;;; ------------------------------------------------------------ section .text global _start _start: ;;; get N from user mov ecx, prompt mov edx, 2 call _printString call _getInput mov dword[N], eax ;;; ------------------------------------------------- ;;; print opening triangle mov ecx, dword[N] for0: mov dword[saveECX], ecx mov edx, dword[N] sub edx, ecx inc edx mov ecx, stars call _printString call _println mov ecx, dword[saveECX] loop for0 ;;; ------------------------------------------------- ;;; print square mov ecx, dword[N] for1: mov dword[saveECX], ecx ;;; print a line of N stars mov ecx, stars mov edx, dword[N] call _printString call _println mov ecx, dword[saveECX] loop for1 ;;; ------------------------------------------------- ;;; print closing triangle mov ecx, dword[N] for2: mov dword[saveECX], ecx mov edx, ecx mov ecx, stars call _printString call _println mov ecx, dword[saveECX] loop for2 ;;; exit() mov eax,1 mov ebx,0 int 0x80 ; final system call
hw5_2.sh
#! /bin/bash # hw5_2.sh # D. Thiebaut # gets a number of the command line and prints a triangle # a square and a triangle with the width equal to the value # of the number. N=$1 for i in $( seq 1 $N ) ; do for j in $( seq 1 $i ) ; do echo -n "*" done echo "" done for i in $( seq 1 $N ) ;do for j in $( seq 1 $N ) ; do echo -n "*" done echo"" done exit for i in $( seq 1 $N ) ;do top=$( expr $N - $i + 1 ) for j in $( seq 1 $top ) ; do echo -n "*" done echo"" done
231b@aurora ~/hw/hw6 $ cat GameOfLife.asm ;;; ; GameOfLife.asm ;;; ; Authors: D. Thiebaut and CSC231 Class ;;; ; ;;; ; Implements a 1-dimensional version of ;;; ; Conway's Game of life. ;;; ; Note that because we do not "know" yet ;;; ; how to test or to use functions, the code ;;; ; is not as efficient as it could be. ;;; ; ;;; ; to assemble and run: ;;; ; ;;; ; nasm -f elf -F stabs GameOfLife.asm ;;; ; ld -melf_i386 -o GameOfLife GameOfLife.o ;;; ; ./GameOfLife ;;; ; ------------------------------------------------------------------- ;;; ------------------------------------------------------------ ;;; data areas ;;; ------------------------------------------------------------ section .data ;;; the current dish with its cells. We use 0 and 1 to ;;; indicate dead and live cells, respectively. %include "dishArray.inc" ;;; the new generation of cells. That's the "future" of the ;;; cells in the dish. We make it the same size as dish, and ;;; fill it with N dead cells. newGen times N db 0 ;;; dishP is a string that will contain ' ' or '!' for ;;; each 0 or 1 in dish. dishP times N db ' ' db 10 ; add a \n at the end ; of dishP generation dd 0 ; save ecx from for generation loop i dd 0 ; used by for loops ;;; ------------------------------------------------------------ ;;; code area ;;; ------------------------------------------------------------ section .text global _start _start: main: ;;; ------------------------------------------------------------- ;;; print( dish ) ;; first we copy dish into dishP and at the same ;; time replace 0 by ' ' and 1 by '!' ;;; for i in range( N ): mov esi, dish mov edi, dishP mov dword[i], 0 forPrint: cmp dword[i], N jge forPrintEnd mov al, byte[esi] add al, ' ' ;0 becomes ' ', 1 becomes '!' mov byte[edi], al inc esi ;esi points to next byte in dish inc edi ;edi points to next byte in dispP ;; i++, loop back inc dword[i] jmp forPrint forPrintEnd: ;; print dishP as a string. mov eax, 4 ;prints dishP to screen mov ebx, 1 mov ecx, dishP ;dishP address mov edx, N+1 ;+1 to include the \n int 0x80 ;;; ----------------------------------------------------------- ;;; for generation in range( maxGen ): mov dword[generation], 0 forGen: mov eax, dword[generation] cmp eax, dword[maxGen] jge forGenEnd ;;; ----------------------------------------------------------- ;;; newGen = life( dish, N ) ;;; newGen[0] = 0 ;;; newGen[N-1] = 0 mov byte[newGen], 0 mov byte[newGen+N-1], 0 ;;; ----------------------------------------------------------- ;;; for i in range( 0, N ): mov esi, dish mov edi, newGen mov dword[i], 0 forLife: cmp dword[i], N jge forLifeEnd ;;; ----------------------------------------------------------- ;;; fate = dish[i-1] ^ dish[i+1] ;;; newGen[i] = fate mov al, byte[esi-1] xor al, byte[esi+1] mov byte[edi], al inc esi inc edi inc dword[i] jmp forLife forLifeEnd: ;;; ----------------------------------------------------------- ;;; dish = newGen mov dword[i],0 mov esi, newGen mov edi, dish forMove: cmp dword[i], N jge forMoveEnd mov al, byte[esi] ;copy newGen[i] to dish[i] mov byte[edi], al inc esi inc edi inc dword[i] loop forMove forMoveEnd: ;;; ------------------------------------------------------------- ;;; print( dish ) ;; first we copy dish into dishP and at the same ;; time replace 0 by ' ' and 1 by '!' ;;; for i in range( N ): mov esi, dish mov edi, dishP mov dword[i], 0 forPrint2: cmp dword[i], N jge forPrintEnd2 mov al, byte[esi] add al, ' ' ;0 becomes ' ', 1 becomes '!' mov byte[edi], al inc esi ;esi points to next byte in dish inc edi ;edi points to next byte in dispP inc dword[i] jmp forPrint2 forPrintEnd2: ;; print dishP as a string. mov eax, 4 ;prints dishP to screen mov ebx, 1 mov ecx, dishP ;dishP address mov edx, N+1 ;+1 to include the \n int 0x80 ;;; ready to loop back to forGen inc dword[generation] jmp forGen forGenEnd: ;;; exit() exit: mov eax,1 mov ebx,0 int 0x80 ; final system call