Difference between revisions of "CSC231 Homework 7 Solution Programs"

From dftwiki3
Jump to: navigation, search
(Comments about the Hints)
(Comments about the Hints)
Line 187: Line 187:
  
 
* See solution program above...
 
* See solution program above...
* Pushing the hints one more step:
+
* Pushing the hints one more step: A python program to generate a lookup table in assembly!
  
 
<br />
 
<br />

Revision as of 09:33, 2 November 2012

--D. Thiebaut 13:21, 1 November 2012 (EDT)


Program 1

  • This solution is from Gavi and shows she got the hints I gave the class about this array of character. The trick here is that since all the characters are listed in order in the string, you have character '0' at index 0 in the string. Character '1' at Index 1. Character '2' at Index 2... Character '9' at Index 9. And now for the magic: Character 'A' is at Index 10. Character 'B' at Index 11, all the way to Character 'F' at Index 15. So we do not need to test whether the number we want to print in hex is less than 10 or not. We just take the number, use it as an index in the string and pull the character that corresponds to it!


;;; ; hw7a.asm
;;; ; Gavi Levy Haskell
;;; ; 231a-ae
;;; ;
;;; ;
;;; ; Displays the contents of a double-word in decimal and
;;; ; hexadecimal.
;;; ;
;;; ; Prints:
;;; ;   x = 305441741 = 0x1234ABCD
;;; ;
;;; ;
;;; ;     nasm -f elf -F  stabs hw7a.asm
;;; ;     gcc -m32 -o hw7a driver.c asm_io.o hw7a.o
;;; ;     ./hw7a

%include "asm_io.inc"
	
	;; -----------------
	;; DATA SECTION
	;; -----------------
	section	.data
x	dd	0x1234ABCD
msg	dd	"  x = ", 0x00
msg2	dd	" = 0x", 0x00
hexChr	db	"0123456789ABCDEF"
	
	;; -----------------
	;; CODE SECTION
	;; -----------------
	section	.text
	global	asm_main
asm_main:
	mov	eax, msg
	call	print_string 	; print "  x = "
	
 	mov	eax, dword[x]
 	call	print_int	; print "305441741"

	mov	eax, msg2
	call	print_string	; print " = 0x"
	
 	mov	ecx, 8
	
for:	mov	ebx, dword[x]	; ebx <-- current rotation of x
 	rol	ebx, 4		; rotate first byte to end
 	mov	dword[x], ebx	; save current rotation in x
 	and	ebx, 0x000000F 	; keep only last digit in ebx

	mov	al, byte[hexChr + ebx]
	call	print_char	; print the character of hexChr
				; corresponding to the digit
	loop	for

	call	print_nl
	
	;; return to C program
	ret


Another good solution that doesn't use the array is provided by Naomi:


;;; hw7a.asm
;;; 231a-ad
;;; Naomi Long
;;;
;;; This program prints the decimal representation of the hex number
;;; 0x1234ABCD and then prints out the hex digits. The output is shown
;;; below, sandwiched between two prompts:
;;; 
;;; [231a-ad@grendel ~/hw7]$ ./hw7a
;;; x = 305441741 = 0x1234ABCD
;;; [231a-ad@grendel ~/hw7]$

	%include "asm_io.inc"

;;;  -------------------------
;;;  data segment
;;;  -------------------------

	section .data
	x	dd	0x1234ABCD
	xeq	db	"x = ",0x00
	eq	db	" = 0x",0x00
	
;;;  -------------------------
;;;  code area
;;;  -------------------------

	section .text
	global  asm_main
asm_main:
;;; print "x = "
	mov	eax, xeq
	call	print_string		; prints "x = "
	
;;; print decimal representation and " = 0x"
	mov	eax, dword[x]
	call	print_int		; prints 305441741
	mov	eax, eq			
	call	print_string		; prints " = 0x"
	
;;; print hex representation
	mov	ecx, 8			; 8 hex digits to loop over
start:
	mov	eax, dword[x]		; gets current hex rotation
	rol	eax, 4			; moves first hex to last position
	mov	dword[x], eax		; saves rotation
	and	eax, 0x0000000f		; remove all but last hex digit
	
	cmp	eax, 10			; check if hex digit letter or number
	jae	letr			; jump to treat letter as ascii char
	
	call	print_int		; prints last hex digit if number
	jmp 	loop			; skip to end of loop
	
letr:	add	eax, 'A'-10		; offset dec to ascii character
	call	print_char		; prints last hex number as ascii char

loop:	loop 	start			; loop to print all 8 hex digits

	call	print_nl		; prints new line after loop is done
	
;;;  return to C program
	ret




Comments

Comments about the programs submitted from the class

  • Put a header above each function. In it put
    • the name of the function
    • the parameters it receives
    • whether it modifies any of the registers
    • what it returns, if any
  • Avoid unreachable code
          ret
          ret
  • Put the last ret instruction at the end of the main function, not at the end of the listing.
  • Don't call functions func1 and func2.
  • If you are working with characters, use a byte register, not a word or double word register.
  • Use self-documenting labels that will help the reader follow the code better:
    • Instead of
             cmp        al, 9
             jgt         grthn
             ...
grthn:
use
             cmp        al, 9
             jgt         printLetter
             ...
printLetter:

  • Don't be afraid to be clever!
 xEqual     db      "x = ", 0x00
 equal       equ      xEqual+1
  • Don't be afraid to double check what you write:
                add      al, 'A'
                sub      al, 10

can be performed with just 1 operation:
                add      al, 'A'-10

Comments about the Hints

  • See solution program above...
  • Pushing the hints one more step: A python program to generate a lookup table in assembly!


# generateTableLookupHexadecimal.py
# D. Thiebaut
# Generates a lookup table for translating a byte into its string equivalent in hex.
#

s = "table\tdb\t"
for i in range(256):
    #print "%d %02X" % (i, i ) 
    if ( i!=0 and i%8==0 ):
        s += "\n\tdb\t"
    else:
        if ( i!=0 ):
            s += ", "
    s += '0x%02X' % i

print s


Output

table	db	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
	db	0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
	db	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
	db	0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
	db	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
	db	0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F
	db	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
	db	0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
	db	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47
	db	0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F
	db	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57
	db	0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
	db	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67
	db	0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F
	db	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77
	db	0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F
	db	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87
	db	0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F
	db	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97
	db	0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F
	db	0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7
	db	0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF
	db	0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7
	db	0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF
	db	0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7
	db	0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF
	db	0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7
	db	0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF
	db	0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7
	db	0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF
	db	0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7
	db	0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF