Difference between revisions of "CSC231 Homework 8 Solution 2012"

From dftwiki3
Jump to: navigation, search
(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 />