Difference between revisions of "CSC231 Homework 8 Solution 2012"
(→Problem #2) |
(→Problem #2) |
||
Line 449: | Line 449: | ||
<br /> | <br /> | ||
<source lang="asm"> | <source lang="asm"> | ||
− | ;;; | + | ;;; ; hw8b.asm |
− | ;;; | + | ;;; ; Gavi Levy Haskell |
− | ;;; | + | ;;; ; 231a-ae |
− | ;;; | + | ;;; ; |
− | ;;; | + | ;;; ; Uses functions to print the first ten |
− | ;;; 01 00 00 00 00 00 00 00 00 00 | + | ;;; ; lines of the Pascal Triangle in hex |
− | ;;; 01 01 00 00 00 00 00 00 00 00 | + | ;;; ; |
− | ;;; 01 02 01 00 00 00 00 00 00 00 | + | ;;; ; prints: |
− | ;;; 01 03 03 01 00 00 00 00 00 00 | + | ;;; ; |
− | ;;; 01 04 06 04 01 00 00 00 00 00 | + | ;;; ; 01 00 00 00 00 00 00 00 00 00 |
− | ;;; 01 05 0A 0A 05 01 00 00 00 00 | + | ;;; ; 01 01 00 00 00 00 00 00 00 00 |
− | ;;; 01 06 0F 14 0F 06 01 00 00 00 | + | ;;; ; 01 02 01 00 00 00 00 00 00 00 |
− | ;;; 01 07 15 23 23 15 07 01 00 00 | + | ;;; ; 01 03 03 01 00 00 00 00 00 00 |
− | ;;; 01 08 1C 38 46 38 1C 08 01 00 | + | ;;; ; 01 04 06 04 01 00 00 00 00 00 |
− | ;;; 01 09 24 54 7E 7E 54 24 09 01 | + | ;;; ; 01 05 0A 0A 05 01 00 00 00 00 |
− | ;;; | + | ;;; ; 01 06 0F 14 0F 06 01 00 00 00 |
− | ;;; | + | ;;; ; 01 07 15 23 23 15 07 01 00 00 |
− | + | ;;; ; 01 08 1C 38 46 38 1C 08 01 00 | |
− | + | ;;; ; 01 09 24 54 7E 7E 54 24 09 01 | |
− | ;; | + | ;;; ; |
− | ;; | + | ;;; ; |
− | ;; | + | ;;; ; nasm -f elf -F stabs hw8b.asm |
− | + | ;;; ; ld -melf_i386 -o hw8b hw8b.o | |
− | Pascal | + | ;;; ; ./hw8b |
− | + | ||
− | + | ;; ----------------- | |
− | + | ;; DATA SECTION | |
− | + | ;; ----------------- | |
− | space | + | section .data |
− | + | Pascal times 10 db 0 | |
− | + | hexChr db "0123456789ABCDEF" | |
− | + | return db 10 | |
− | + | space db " " | |
− | + | ||
− | ;; | + | ;; ----------------- |
− | ;; | + | ;; CODE SECTION |
− | ;; | + | ;; ----------------- |
− | + | section .text | |
− | + | global _start | |
− | |||
− | |||
− | |||
− | |||
_start: | _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 | ||
+ | call printArray ; print Pascal array | ||
− | + | mov ebx, Pascal | |
− | + | call nextLine ; compute next line of triangle | |
− | |||
− | + | loop for | |
− | |||
− | |||
− | |||
;;; exit | ;;; exit | ||
− | + | mov eax, 1 | |
− | + | mov ebx, 0 | |
− | + | int 0x80 | |
− | ;; | + | ;;; init |
− | ; | + | ;;; recieves address of Pascal in ebx |
− | ;; | + | ;;; modifies no registers |
− | ; | ||
− | ; | ||
− | ;; | ||
init: | init: | ||
− | + | mov dword[ebx], 0 ; change first 4 terms to zero | |
− | + | mov dword[ebx + 4], 0 ; change next 4 terms to 0 | |
− | + | mov word[ebx + 8], 0 ; change last 2 terms to 0 | |
− | + | mov byte[ebx], 1 ; change first term of array to 1 | |
− | + | ret | |
− | |||
− | |||
− | ; | + | ;;; printArray |
− | ;; | + | ;;; recieves address of Pascal in ebx |
− | ;; in ebx | + | ;;; modifies eax, ebx, edx |
− | ;; | ||
− | ; | ||
− | |||
− | |||
printArray: | printArray: | ||
− | + | push ecx ; save outer loop position | |
− | + | mov ecx, 10 | |
− | + | .for: | |
− | + | push ecx ; save loop position | |
− | + | push ebx ; save address | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | mov cl, byte[ebx] ; first digit | |
− | + | ror ecx, 4 ; get correct digit | |
− | + | and ecx, 0x0F ; keep only this digit | |
+ | add ecx, hexChr ; add address of hexChr | ||
+ | mov eax, 4 | ||
+ | mov ebx, 1 | ||
+ | mov edx, 1 | ||
+ | int 0x80 ; print first digit | ||
− | + | pop ebx | |
+ | push ebx | ||
+ | mov cl, byte[ebx] ; second digit | ||
+ | and ecx, 0x0F ; keep only this digit | ||
+ | add ecx, hexChr ; add address of hexChr | ||
+ | mov eax, 4 | ||
+ | mov ebx, 1 | ||
+ | mov edx, 1 | ||
+ | int 0x80 ; print second digit | ||
− | + | mov eax, 4 | |
− | + | mov ebx, 1 | |
− | ; | + | mov ecx, space |
− | + | mov edx, 1 | |
− | + | int 0x80 ; print space | |
− | + | ||
− | + | pop ebx | |
− | + | pop ecx ; retrieve loop position | |
+ | add ebx, 1 | ||
+ | |||
+ | loop .for ; retrieve outer loop position | ||
− | + | mov eax, 4 | |
− | + | mov ebx, 1 | |
− | + | mov ecx, return ; return | |
− | + | mov edx, 1 | |
− | + | int 0x80 ; next line | |
− | + | ||
+ | pop ecx | ||
+ | ret | ||
− | + | ;;; nextLine | |
− | + | ;;; recieves address of Pascal in ebx | |
+ | ;;; modifies eax, ebx | ||
+ | nextLine: | ||
+ | push ecx ; save outer loop position | ||
+ | mov ecx, 9 | ||
+ | add ebx, 9 | ||
+ | .for: | ||
+ | push ecx ; save loop position | ||
+ | mov al, byte[ebx - 1] ; n = row[x - 1] | ||
+ | add byte[ebx], al ; row[x] += n | ||
+ | dec ebx ; x -= 1 | ||
+ | pop ecx ; retrieve loop position | ||
+ | loop .for | ||
+ | pop ecx ; retrieve loop position | ||
+ | ret | ||
</source> | </source> | ||
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> | <br /><br /><br /><br /><br /><br /><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]] | [[Category:CSC231]][[Category:Homework]] |
Revision as of 12:29, 13 November 2012
--D. Thiebaut 12:15, 13 November 2012 (EST)
Problem #1, Version 1
This version contains the complete code. Version 2 below separates the dumpRegs functions and main program into two files.
;;; ---------------------------------------------------------
;;; 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
Problem #1, Version 2
Main Program
;;; ---------------------------------------------------------
;;; 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
Library
;;; ---------------------------------------------------------
;;; 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
Problem #2
;;; ; hw8b.asm
;;; ; Gavi Levy Haskell
;;; ; 231a-ae
;;; ;
;;; ; Uses functions to print the first ten
;;; ; lines of the Pascal Triangle in hex
;;; ;
;;; ; prints:
;;; ;
;;; ; 01 00 00 00 00 00 00 00 00 00
;;; ; 01 01 00 00 00 00 00 00 00 00
;;; ; 01 02 01 00 00 00 00 00 00 00
;;; ; 01 03 03 01 00 00 00 00 00 00
;;; ; 01 04 06 04 01 00 00 00 00 00
;;; ; 01 05 0A 0A 05 01 00 00 00 00
;;; ; 01 06 0F 14 0F 06 01 00 00 00
;;; ; 01 07 15 23 23 15 07 01 00 00
;;; ; 01 08 1C 38 46 38 1C 08 01 00
;;; ; 01 09 24 54 7E 7E 54 24 09 01
;;; ;
;;; ;
;;; ; nasm -f elf -F stabs hw8b.asm
;;; ; ld -melf_i386 -o hw8b hw8b.o
;;; ; ./hw8b
;; -----------------
;; DATA SECTION
;; -----------------
section .data
Pascal times 10 db 0
hexChr db "0123456789ABCDEF"
return db 10
space db " "
;; -----------------
;; CODE SECTION
;; -----------------
section .text
global _start
_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
call printArray ; print Pascal array
mov ebx, Pascal
call nextLine ; compute next line of triangle
loop for
;;; exit
mov eax, 1
mov ebx, 0
int 0x80
;;; init
;;; recieves address of Pascal in ebx
;;; modifies no registers
init:
mov dword[ebx], 0 ; change first 4 terms to zero
mov dword[ebx + 4], 0 ; change next 4 terms to 0
mov word[ebx + 8], 0 ; change last 2 terms to 0
mov byte[ebx], 1 ; change first term of array to 1
ret
;;; printArray
;;; recieves address of Pascal in ebx
;;; modifies eax, ebx, edx
printArray:
push ecx ; save outer loop position
mov ecx, 10
.for:
push ecx ; save loop position
push ebx ; save address
mov cl, byte[ebx] ; first digit
ror ecx, 4 ; get correct digit
and ecx, 0x0F ; keep only this digit
add ecx, hexChr ; add address of hexChr
mov eax, 4
mov ebx, 1
mov edx, 1
int 0x80 ; print first digit
pop ebx
push ebx
mov cl, byte[ebx] ; second digit
and ecx, 0x0F ; keep only this digit
add ecx, hexChr ; add address of hexChr
mov eax, 4
mov ebx, 1
mov edx, 1
int 0x80 ; print second digit
mov eax, 4
mov ebx, 1
mov ecx, space
mov edx, 1
int 0x80 ; print space
pop ebx
pop ecx ; retrieve loop position
add ebx, 1
loop .for ; retrieve outer loop position
mov eax, 4
mov ebx, 1
mov ecx, return ; return
mov edx, 1
int 0x80 ; next line
pop ecx
ret
;;; nextLine
;;; recieves address of Pascal in ebx
;;; modifies eax, ebx
nextLine:
push ecx ; save outer loop position
mov ecx, 9
add ebx, 9
.for:
push ecx ; save loop position
mov al, byte[ebx - 1] ; n = row[x - 1]
add byte[ebx], al ; row[x] += n
dec ebx ; x -= 1
pop ecx ; retrieve loop position
loop .for
pop ecx ; retrieve loop position
ret