Difference between revisions of "CSC231 Homework 8 Solution 2012"
(Created page with "--~~~~ ---- =Problem #1, Version 1= <br /> <source lang="asm"> ;;; --------------------------------------------------------- ;;; hw8aSol.asm ;;; D. Thiebaut ;;; 11/13/12 ;;; Th...") |
(→Problem #1, Version 1) |
||
Line 2: | Line 2: | ||
---- | ---- | ||
=Problem #1, Version 1= | =Problem #1, Version 1= | ||
− | + | This version contains the complete code. Version 2 below separates the dumpRegs functions and main program into two files. | |
<br /> | <br /> | ||
<source lang="asm"> | <source lang="asm"> | ||
Line 209: | Line 209: | ||
<br /> | <br /> | ||
+ | =Problem #1, Version 2= | ||
+ | ==Main Program== | ||
+ | <br /> | ||
+ | <source lang="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 | ||
+ | </source> | ||
+ | <br /> | ||
+ | ==Library== | ||
+ | <br /> | ||
+ | <source lang="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 | ||
+ | </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 /><br /> | ||
[[Category:CSC231]][[Category:Homework]] | [[Category:CSC231]][[Category:Homework]] |
Revision as of 12:21, 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
</br />