Difference between revisions of "CSC231 Homework Solutions 2017"
(16 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
--[[User:Thiebaut|D. Thiebaut]] ([[User talk:Thiebaut|talk]]) 17:57, 22 April 2017 (EDT) | --[[User:Thiebaut|D. Thiebaut]] ([[User talk:Thiebaut|talk]]) 17:57, 22 April 2017 (EDT) | ||
---- | ---- | ||
+ | <onlydft> | ||
=Problem 1= | =Problem 1= | ||
::<source lang="asm"> | ::<source lang="asm"> | ||
Line 132: | Line 133: | ||
</source> | </source> | ||
+ | <br /> | ||
+ | =hw2.asm= | ||
+ | <br /> | ||
+ | ::<source lang="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 | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | =Teller.asm= | ||
+ | <br /> | ||
+ | ::<source lang="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 | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | =hw5_1.asm= | ||
+ | <br /> | ||
+ | ::<source lang="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 | ||
+ | |||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | |||
+ | =hw5_2.sh= | ||
+ | <br /> | ||
+ | ::<source lang="bash"> | ||
+ | #! /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 | ||
+ | </source> | ||
+ | <br /> | ||
+ | =GameOfLife.asm= | ||
+ | ::<source lang="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 /> | ||
+ | =hw7_1.C= | ||
+ | <br /> | ||
+ | ::<source lang="C"> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <string.h> | ||
+ | |||
+ | int main( int argc, char *argv[] ) { | ||
+ | int n, i, name; | ||
+ | char sentence[100]; | ||
+ | char stars[100]; | ||
+ | |||
+ | if ( argc < 2 ) { | ||
+ | printf( "Syntax: %s string [string...]\n", argv[0] ); | ||
+ | exit( 1 ); | ||
+ | } | ||
+ | |||
+ | strcpy( sentence, "* " ); | ||
+ | for ( i = 1; i < argc; i++ ) { | ||
+ | if ( i > 1 ) | ||
+ | strcat( sentence, " " ); | ||
+ | strcat( sentence, argv[i] ); | ||
+ | } | ||
+ | strcat( sentence, " *" ); | ||
+ | |||
+ | // printf( "%s\n", sentence ); | ||
+ | |||
+ | n = (int) strlen( sentence ); | ||
+ | |||
+ | strcpy( stars, "*" ); | ||
+ | for ( i=0; i<strlen( stars)-1; i++ ) | ||
+ | strcat( stars, "*" ); | ||
+ | |||
+ | for ( i=0; i< n-1; i++ ) { | ||
+ | stars[i+1] = '\0'; | ||
+ | printf( "%s\n", stars ); | ||
+ | stars[i+1] = '*'; | ||
+ | } | ||
+ | |||
+ | printf( "%s\n", sentence ); | ||
+ | |||
+ | for ( i=n-2; i>= 0; i-- ) { | ||
+ | stars[i+1] = '\0'; | ||
+ | printf( "%s\n", stars ); | ||
+ | stars[i+1] = '*'; | ||
+ | } | ||
+ | |||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </source> | ||
+ | <br /> | ||
+ | =hw7_2.asm= | ||
+ | <br /> | ||
+ | ::<source lang="asm"> | ||
+ | ;;; ; ------------------------------------------------------------------- | ||
+ | ;;; ; hw4b.asm | ||
+ | ;;; ; Julia Burch | ||
+ | ;;; ; 231a-aa | ||
+ | ;;; ; | ||
+ | ;;; ; Computes and prints the first 10 rows of Pascal's triangle. | ||
+ | ;;; ; OUTPUT: | ||
+ | ;;; ; 1 0 0 0 0 0 0 0 0 0 | ||
+ | ;;; ; 1 1 0 0 0 0 0 0 0 0 | ||
+ | ;;; ; 1 2 1 0 0 0 0 0 0 0 | ||
+ | ;;; ; 1 3 3 1 0 0 0 0 0 0 | ||
+ | ;;; ; 1 4 6 4 1 0 0 0 0 0 | ||
+ | ;;; ; 1 5 10 10 5 1 0 0 0 0 | ||
+ | ;;; ; 1 6 15 20 15 6 1 0 0 0 | ||
+ | ;;; ; 1 7 21 35 35 21 7 1 0 0 | ||
+ | ;;; ; 1 8 28 56 70 56 28 8 1 0 | ||
+ | ;;; ; 1 9 36 84 126 126 84 36 9 1 | ||
+ | ;;; ; to assemble and run: | ||
+ | ;;; ; | ||
+ | ;;; ; nasm -f elf -F stabs hw4b.asm | ||
+ | ;;; ; gcc -o hw4b driver.c asm_io.o hw4b.o | ||
+ | ;;; ; ./hw4b | ||
+ | ;;; ; ------------------------------------------------------------------- | ||
+ | |||
+ | ;; %include files here... | ||
+ | extern _printDec | ||
+ | extern _println | ||
+ | extern _printString | ||
+ | |||
+ | ;;; ------------------------------------------------------------ | ||
+ | ;;; data areas | ||
+ | ;;; ------------------------------------------------------------ | ||
+ | |||
+ | section .data | ||
+ | |||
+ | shift db 0 | ||
+ | pascal db 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
+ | temp dd 0 | ||
+ | space db 9 | ||
+ | rows equ 10 | ||
+ | ;;; ------------------------------------------------------------ | ||
+ | ;;; code area | ||
+ | ;;; ------------------------------------------------------------ | ||
+ | |||
+ | section .text | ||
+ | global _start | ||
+ | |||
+ | _start: | ||
+ | |||
+ | ;; move first line of Pascal into edi, then rows into ecx | ||
+ | ;; to initialize and run for loop 10 times. | ||
+ | mov edi, pascal | ||
+ | mov ecx, rows | ||
+ | main: | ||
+ | ;; store ecx in a temporary variable, move rows into ecx to initialize | ||
+ | ;; and run print_triangle loop. Move the first line into edi | ||
+ | ;; and 0 into esi. | ||
+ | push ecx | ||
+ | mov ecx, rows | ||
+ | mov edi, pascal | ||
+ | mov esi, 0 | ||
+ | |||
+ | print_triangle: | ||
+ | ;; print the int in al, print tab and then clear | ||
+ | ;; tab from register. | ||
+ | push ecx | ||
+ | mov al, byte[edi+esi] | ||
+ | call _printDec | ||
+ | |||
+ | mov ecx, space | ||
+ | mov edx, 1 | ||
+ | call _printString | ||
+ | |||
+ | mov eax, 0 | ||
+ | inc esi | ||
+ | |||
+ | pop ecx | ||
+ | loop print_triangle | ||
+ | |||
+ | ;; print a new line | ||
+ | call _println | ||
+ | |||
+ | ;; load newly calculated pascal line into edi, then shift the row | ||
+ | mov edi, pascal | ||
+ | mov esi, shift | ||
+ | mov ecx, rows-1 | ||
+ | |||
+ | calculate: | ||
+ | ;; move pascal digit into al, add it to previous row's, store the value | ||
+ | mov al, byte[edi+ecx] | ||
+ | add al, byte[esi+ecx] | ||
+ | mov byte[edi+ecx], al | ||
+ | |||
+ | loop calculate | ||
+ | |||
+ | ;; restore value of ecx for loop | ||
+ | pop ecx | ||
+ | loop main | ||
+ | |||
+ | ;;; exit() | ||
+ | mov ebx, 0 | ||
+ | mov eax, 1 | ||
+ | int 0x80 | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | =hw7_3.asm (mystery program)= | ||
+ | <br /> | ||
+ | ::<source lang="asm"> | ||
+ | |||
+ | ;;; helloWorld.asm | ||
+ | ;;; D. Thiebaut | ||
+ | ;;; | ||
+ | ;;; To assemble, link, and run: | ||
+ | ;;; nasm -f elf helloWorld.asm | ||
+ | ;;; ld -melf_i386 -o helloWorld helloWorld.o | ||
+ | ;;; ./helloWorld | ||
+ | ;;; | ||
+ | |||
+ | section .data | ||
+ | db "Mystery", 0 | ||
+ | msg1 db "Vive le chacalot au lait!", 0 | ||
+ | msg2 db "Assembly is fun!", 0 | ||
+ | msg3 db 0x01, 0x02, 0x03 | ||
+ | x dd 128 | ||
+ | y dd 64 | ||
+ | HelloLen equ $-msg1 | ||
+ | |||
+ | section .text | ||
+ | |||
+ | _mystery: | ||
+ | |||
+ | ;;; print message | ||
+ | add byte[msg1+10],'o'-'a' | ||
+ | add byte[msg1+12],'o'-'a' | ||
+ | add byte[msg1+14],'a'-'o' | ||
+ | mov eax, 4 ; write | ||
+ | mov ebx, 1 ; stdout | ||
+ | mov ecx, msg1+8 | ||
+ | mov edx, 8 ; # of chars to print | ||
+ | int 0x80 | ||
+ | |||
+ | mov eax, dword[x] | ||
+ | add eax, 0xFFFFFFFF | ||
+ | xor ebx, ebx | ||
+ | mov bx, word[y] | ||
+ | shl bx,16 | ||
+ | mov edx, 0x12345678 | ||
+ | mov dx, ax | ||
+ | mov ecx, 10 | ||
+ | loop there | ||
+ | there: | ||
+ | |||
+ | ;;; exit | ||
+ | mov ebx, 0 | ||
+ | mov eax, 1 | ||
+ | int 0x80 | ||
+ | </source> | ||
+ | <!-- ========================================================= --> | ||
+ | <br /> | ||
+ | =hw8_1.c= | ||
+ | <br /> | ||
+ | ::<source lang="C"> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <string.h> | ||
+ | |||
+ | |||
+ | void main( int argc, char *argv[] ) { | ||
+ | char *marker1, *marker2, *DNA; | ||
+ | char *fileName; | ||
+ | |||
+ | if (argc < 4 ) { | ||
+ | printf( "syntax: %s marker1 marker2 DNA\n", argv[0] ); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | marker1 = argv[1]; | ||
+ | marker2 = argv[2]; | ||
+ | DNA = argv[3]; | ||
+ | |||
+ | //--- print the markers and DNA --- | ||
+ | /* (for debugging purposes) | ||
+ | printf( "Marker1 = %s\n", marker1 ); | ||
+ | printf( "Marker2 = %s\n", marker2 ); | ||
+ | if ( strlen( DNA ) > 80 ) | ||
+ | printf( "DNA = %.*s...%s (%d bases)\n\n", | ||
+ | 10, DNA, DNA+((int)strlen(DNA)-10), | ||
+ | (int) strlen( DNA) ); | ||
+ | else | ||
+ | printf( "DNA = %s\n\n", DNA ); | ||
+ | */ | ||
+ | |||
+ | //--- add your code below this point --- | ||
+ | char *first, *second; | ||
+ | first = strstr( DNA, marker1 ); | ||
+ | if ( first == NULL ) { | ||
+ | printf( "%s\n", DNA ); | ||
+ | return; | ||
+ | } | ||
+ | second = strstr( first+1, marker2 ); | ||
+ | if ( second == NULL ) { | ||
+ | printf( "%s\n", DNA ); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | char *p; | ||
+ | for ( p= first; p < second+strlen(marker2); p++ ) | ||
+ | *p = '-'; | ||
+ | |||
+ | printf( "%s\n", DNA ); | ||
+ | } | ||
+ | |||
+ | </source> | ||
+ | =hw8_2.asm= | ||
+ | <br /> | ||
+ | ::<source lang="asm"> | ||
+ | ; hw8_2.asm | ||
+ | ; D. Thiebaut | ||
+ | |||
+ | global f1 | ||
+ | global f2 | ||
+ | global f3 | ||
+ | |||
+ | ;;; ------------------------------------------------------ | ||
+ | ;;; f1( s ): modifies s in place and make it uppercase. | ||
+ | f1: push ebp | ||
+ | mov ebp, esp | ||
+ | push ebx | ||
+ | mov ebx, dword[ebp+8] | ||
+ | .for: cmp byte[ebx], 0 | ||
+ | je .done | ||
+ | cmp byte[ebx],'a' | ||
+ | jl .endfor | ||
+ | cmp byte[ebx],'z' | ||
+ | jg .endfor | ||
+ | add byte[ebx],'A'-'a' | ||
+ | .endfor: | ||
+ | inc ebx | ||
+ | jmp .for | ||
+ | .done: | ||
+ | pop ebx | ||
+ | pop ebp | ||
+ | ret 4 | ||
+ | |||
+ | ;;; ------------------------------------------------------ | ||
+ | ;;; f2( a, b, c ) | ||
+ | ;;; returns 2a + 3b -c in eax | ||
+ | ;;; computes it as 2(a+b) + b - c (fewer operations) | ||
+ | f2: push ebp | ||
+ | mov ebp, esp | ||
+ | mov eax, dword[ebp+8+4+4] ; get first param | ||
+ | add eax, dword[ebp+8+4] ; eax <- a+b | ||
+ | add eax, eax ; eax <- 2(a+b) | ||
+ | add eax, dword[ebp+8+4] ; eax <- 2(a+b) + b | ||
+ | sub eax, dword[ebp+8] ; eax <- 2a + 3b -c | ||
+ | pop ebp ; | ||
+ | ret 4*3 ; return and get rid of 3 ints | ||
+ | |||
+ | |||
+ | ;;; ------------------------------------------------------ | ||
+ | ;;; f3( array, n ) | ||
+ | ;;; computes the number of even ints in array, of length n. | ||
+ | ;;; returns this number in eax. | ||
+ | f3: push ebp | ||
+ | mov ebp, esp | ||
+ | |||
+ | ;;; push ebx | ||
+ | push ecx | ||
+ | |||
+ | mov ebx, dword[ebp+8+4] ; ebx <- array | ||
+ | mov ecx, dword[ebp+8] ; ecx <- n | ||
+ | mov eax, 0 ; number of even ints | ||
+ | .for: and dword[ebx], 1 ; and array[i] with 1 | ||
+ | jnz .notEven ; if result is 1, then odd number | ||
+ | .even: inc eax ; otherwise, add 1 to counter. | ||
+ | .notEven: | ||
+ | add ebx, 4 | ||
+ | loop .for | ||
+ | |||
+ | ;;; pop ecx | ||
+ | pop ebx | ||
+ | |||
+ | pop ebp | ||
+ | ret 2*4 | ||
+ | |||
+ | |||
+ | </source> | ||
+ | <!-- ================================================================= --> | ||
+ | |||
+ | =Homework 9: funcs.c= | ||
+ | <br /> | ||
+ | ::<source lang="c"> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <string.h> | ||
+ | |||
+ | // getMax: returns the largest of 3 integers passed | ||
+ | // by value | ||
+ | int getMin( int a, int b, int c ) { | ||
+ | if ( a <= b && a <= c ) | ||
+ | return a; | ||
+ | if ( b <= a && b <= c ) | ||
+ | return b; | ||
+ | return c; | ||
+ | } | ||
+ | |||
+ | // zap: given a string haystack, and a string needle, | ||
+ | // looks for the firlst location of needle in the haystack, and | ||
+ | // when it finds it, replaces it with dashes. Example | ||
+ | // char s1[] = "Mississippi"; | ||
+ | // char s2[] = "ss"; | ||
+ | // char *p = s1, *q = s2; | ||
+ | // zap( s1, s2 ) will replace s1 with "Mi--issippi". | ||
+ | // zap( s1, "mm" ) will leave s1 unchanged. | ||
+ | // Returns 0 if zap couldn't fine the needle in | ||
+ | // the haystack. Returns 1 if some character replacement | ||
+ | // took place. | ||
+ | int zap( char *haystack, char *needle ) { | ||
+ | char *p = strstr( haystack, needle ); | ||
+ | char *q; | ||
+ | if ( p==NULL ) | ||
+ | return 0; | ||
+ | for ( q=p; q != p+strlen( needle ); q++ ) | ||
+ | *q = '-'; | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | // merge(): takes two sorted arrays of ints of length 5 | ||
+ | // and merges them into an array of length 10, so that | ||
+ | // the third array is sorted, in increasing order. | ||
+ | void merge( int A[], int B[], int C[] ) { | ||
+ | int i = 0; | ||
+ | int j = 0; | ||
+ | int k = 0; | ||
+ | while ( 1 ) { | ||
+ | if ( A[i] < B[j] ) { | ||
+ | C[k++] = A[i++]; | ||
+ | //printf( "A[%d] (%d) < B[%d] (%d) ==> C[%d] (%d)\n", i-1, A[i-1], j, B[j], k-1, C[k-1] ); | ||
+ | } | ||
+ | else { | ||
+ | C[k++] = B[j++]; | ||
+ | //printf( "A[%d] (%d) > B[%d] (%d) ==> C[%d] (%d)\n", i, A[i], j-1, B[j-1], k-1, C[k-1] ); | ||
+ | } | ||
+ | if ( i>=5 || j>=5 ) | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | while ( i<5 && k <10 ) { | ||
+ | C[k++] = A[i++]; | ||
+ | //printf( "C[%d] (%d) <-- A[%d] (%d)\n", k-1, C[k-1], i-1, A[i-1] ); | ||
+ | } | ||
+ | while ( j<5 && k <10 ) { | ||
+ | C[k++] = B[j++]; | ||
+ | //printf( "C[%d] (%d) <-- B[%d] (%d)\n", k-1, C[k-1], j-1, B[j-1] ); | ||
+ | |||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | =Homework 9: hanoi.asm= | ||
+ | <br /> | ||
+ | ::<source lang="asm"> | ||
+ | ;;; hanoi.asm | ||
+ | ;;; D. Thiebaut | ||
+ | ;;; | ||
+ | ;;; This program solves the "Towers of Hanoi" program | ||
+ | ;;; in assembly. It prompts the user for an integer | ||
+ | ;;; number of disks (must be larger than 0) and displays | ||
+ | ;;; the name of the peg from which to move a disk, and | ||
+ | ;;; the name of the peg to move it to. The pegs are | ||
+ | ;;; labeled 'A', 'B', and 'C', and the disks are always | ||
+ | ;;; assumed to moved originally from 'A' to 'B'. | ||
+ | ;;; To assemble, link, and run: | ||
+ | ;;; nasm -f elf 231Lib.o | ||
+ | ;;; nasm -f elf hanoi.asm | ||
+ | ;;; ld -melf_i386 -o hanoi hanoi.o 231Lib.o | ||
+ | ;;; ./hanoi 3 | ||
+ | ;;; | ||
+ | |||
+ | section .data | ||
+ | N dd 5 | ||
+ | |||
+ | section .text | ||
+ | extern _getInput | ||
+ | extern _println | ||
+ | extern _printString | ||
+ | extern _atoi | ||
+ | global _start | ||
+ | _start: | ||
+ | |||
+ | ;;; get N from command line | ||
+ | ;;; When any assembly language program starts, the operating system | ||
+ | ;;; passes it argc and argv through the statck. The esp register | ||
+ | ;;; points to argc. at esp+4, is a pointer to the beginning of argv[0], | ||
+ | ;;; as a string. At esp+8 is a pointer to the beginning of argv[1], | ||
+ | ;;; as a string. | ||
+ | |||
+ | mov ebp, esp | ||
+ | mov eax, dword[ebp] ; put argc into eax | ||
+ | ;;; call _printDec ; print it | ||
+ | ;;; call _println | ||
+ | |||
+ | mov eax, dword[ebp+4+4] ; make eax points to arv[1] | ||
+ | call _atoi ; convert ascii string to int | ||
+ | mov dword[N], eax ; save N | ||
+ | |||
+ | |||
+ | ;;; define the 3 pegs and pass them in bl, cl, and dl. | ||
+ | |||
+ | mov bl, 'A' | ||
+ | mov cl, 'B' | ||
+ | mov dl, 'C' | ||
+ | |||
+ | ;;; moveDisks( N, 'A', 'B', 'C' ) ; eax <- N | ||
+ | call moveDisks ; bl <- 'A' | ||
+ | ; cl <- 'B' | ||
+ | ; dl <- 'C' | ||
+ | |||
+ | |||
+ | ;;; exit | ||
+ | mov ebx, 0 | ||
+ | mov eax, 1 | ||
+ | int 0x80 | ||
+ | |||
+ | |||
+ | ;;; ------------------------------------------------------------------ | ||
+ | ;;; moveDisks( n, source, dest, extra ) | ||
+ | ;;; eax bl cl dl | ||
+ | ;;; Moves the n disks from source to dest using extra if necessary. | ||
+ | ;;; Uses recursion to move the N-1 disks above the last one. | ||
+ | ;;; Does not modify any of the registers | ||
+ | ;;; ------------------------------------------------------------------ | ||
+ | moveDisks: pushad | ||
+ | |||
+ | ;;; if n==1: | ||
+ | ;;; print( source, dest ) | ||
+ | cmp eax, 1 | ||
+ | jg recurse | ||
+ | mov al, bl ; print source | ||
+ | call printChar | ||
+ | mov al, ' ' ; print space | ||
+ | call printChar | ||
+ | mov al, cl ; print dest | ||
+ | call printChar | ||
+ | call _println ; print \n | ||
+ | |||
+ | popad ; done! return | ||
+ | ret | ||
+ | |||
+ | recurse: | ||
+ | ;;; moveDisks( n-1, source, temp, dest ) | ||
+ | dec eax ; eax <- n-1 | ||
+ | xchg cl, dl ; swap cl & dl | ||
+ | call moveDisks ; move n-1 | ||
+ | xchg cl, dl ; swap them back | ||
+ | |||
+ | |||
+ | ;;; print( source, dest ) | ||
+ | mov al, bl ; print source | ||
+ | call printChar | ||
+ | mov al, ' ' ; print space | ||
+ | call printChar | ||
+ | mov al, cl ; print dest | ||
+ | call printChar | ||
+ | call _println ; print \n | ||
+ | |||
+ | ;;; moveDisks( n-1, temp, dest, source ) | ||
+ | popad ; get all the original parameters back | ||
+ | pushad ; and push them back in the stack | ||
+ | xchg bl, dl ; exchange source and temp | ||
+ | dec eax ; eax <-- n-1 | ||
+ | call moveDisks ; recurse | ||
+ | |||
+ | popad ; pop all registers back | ||
+ | ret | ||
+ | |||
+ | ;;; ------------------------------------------------------------------ | ||
+ | ;;; printChar: prints the character in al | ||
+ | ;;; does not modify any other register | ||
+ | ;;; ------------------------------------------------------------------ | ||
+ | section .data | ||
+ | char db 'A' | ||
+ | section .text | ||
+ | printChar: pushad | ||
+ | mov byte[char],al | ||
+ | mov ecx, char | ||
+ | mov edx, 1 | ||
+ | call _printString | ||
+ | popad | ||
+ | ret | ||
+ | |||
+ | |||
+ | |||
+ | </source> | ||
+ | </onlydft> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | [[Category:CSC231]][[Category:Homework]] |