Difference between revisions of "CSC231 Homework 6 Solution"
(New page: <code><pre> ;;; hw6.asm ;;; Amy Gray ;;; This program reads a bmp file into memory and decodes a secret ;;; message hidden in the pixels via steganography ;;; %include "mytools2.inc" ; f...) |
|||
Line 1: | Line 1: | ||
<code><pre> | <code><pre> | ||
;;; hw6.asm | ;;; hw6.asm | ||
− | ;;; | + | ;;; Ellysha Raelen Recto |
− | ;;; This program reads a bmp file | + | ;;; |
− | ;;; | + | ;;; This program written from the skeleton program, makegreyBmp.asm, written |
+ | ;;; by D. Thiebaut. This program reads a bmp file and reads the last bit of | ||
+ | ;;; each byte. The bytes read contains a secret msg which is then displayed. | ||
;;; | ;;; | ||
%include "mytools2.inc" ; for basic printing to the screen | %include "mytools2.inc" ; for basic printing to the screen | ||
%include "fileio2.inc" ; for basic file operations | %include "fileio2.inc" ; for basic file operations | ||
− | + | ||
%assign SYS_EXIT 1 | %assign SYS_EXIT 1 | ||
%assign MAXPIXEL 5000000 | %assign MAXPIXEL 5000000 | ||
+ | |||
+ | %assign SYS_WRITE 4 | ||
+ | %assign STDOUT 1 | ||
%assign RED 2 | %assign RED 2 | ||
Line 23: | Line 28: | ||
errorMsg db "Error accessing file!",0x0A | errorMsg db "Error accessing file!",0x0A | ||
errorLen equ $-errorMsg | errorLen equ $-errorMsg | ||
− | + | msg db 0 | |
section .bss | section .bss | ||
− | filename resb 255 | + | filename resb 255 ; reserve 255 chars for filename |
handle resd 1 ; file descriptor | handle resd 1 ; file descriptor | ||
noRead resd 1 ; contains number of bytes read | noRead resd 1 ; contains number of bytes read | ||
lWidth resd 1 ; the line width rounded to the nearest | lWidth resd 1 ; the line width rounded to the nearest | ||
− | ; dword boundary lWidth=(((width-1)/4)+1)*4 | + | ; dword boundary lWidth=(((width-1)/4)+1)*4 |
;;; ---------------------------------------------------------- | ;;; ---------------------------------------------------------- | ||
Line 83: | Line 88: | ||
cmp al,0 | cmp al,0 | ||
jne copy | jne copy | ||
− | + | ||
;;; --- open file --- | ;;; --- open file --- | ||
openFile filename, [handle], errorMsg, errorLen | openFile filename, [handle], errorMsg, errorLen | ||
Line 115: | Line 120: | ||
− | ;; | + | ;; ----------------------------------- |
− | + | ;; add your byte-examining loop below! | |
− | ;; | + | ;; you can access the bytes of the pixels as byte[ebx+pixelBuf] |
− | + | ;; and increment ebx in the loop to access successive bytes | |
− | ;; | + | ;; ----------------------------------- |
− | |||
− | ;; | ||
− | |||
− | |||
− | ;; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ;; ----------------------------------- | |
− | + | ;; mainFor: main section for reading secret bytes | |
− | + | ;; written by: Ellysha Raelen Recto | |
− | + | ;; registers modified: none | |
− | + | ;; ----------------------------------- | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | mainFor: | ||
+ | call decode1byte ; calls method to decode 1 byte of secret msg | ||
+ | cmp dl, 0 ; if 1 byte is zero, end of secret msg | ||
+ | je exit ; go to exit if end of msg is found | ||
+ | call printByte ; print byte | ||
+ | jmp mainFor ; decode more bytes if end of msg isnt found | ||
;; ----------------------------------- | ;; ----------------------------------- | ||
;; end of pixel loop area | ;; end of pixel loop area | ||
;; ----------------------------------- | ;; ----------------------------------- | ||
− | + | ||
;;; --- position file pointer back to beginning of file --- | ;;; --- position file pointer back to beginning of file --- | ||
seek0 [handle] | seek0 [handle] | ||
Line 166: | Line 151: | ||
;;; --- close file --- | ;;; --- close file --- | ||
close [handle] | close [handle] | ||
− | + | ||
;;; --- exit() --- | ;;; --- exit() --- | ||
exit: | exit: | ||
Line 204: | Line 189: | ||
ret 8 | ret 8 | ||
− | + | ;;; ------------------------------------------------------------- | |
− | ;;; -------------------------------------------------------- | + | ;;; decode1byte: decodes 1 byte of secret msg, first bit of the byte |
− | ;;; decode1byte: | + | ;;; is from the last bit of first 8th byte of image |
− | ;;; | + | ;;; registers modified: edx, ecx, eax, ebx |
− | ;;; | + | ;;; written by: Ellysha Raelen Recto |
− | + | ;;; ------------------------------------------------------------- | |
− | |||
− | |||
− | ;;; | ||
− | ;;; ------------------------------------------------------- | ||
− | |||
decode1byte: | decode1byte: | ||
− | + | mov dl, 0 | |
− | + | mov ecx,7 ; reads first 7 bits | |
− | + | for: call read1bit ; call method to read 1 bit with shifting | |
− | + | dec ebx ; goes to next bit | |
− | mov | + | loop for |
− | + | mov al, byte[ebx+pixelBuf+7] ; reads last bit | |
− | + | and al, 1 | |
+ | or dl, al | ||
+ | add ebx, 15 | ||
+ | ret | ||
− | + | ;;; ------------------------------------------------------------- | |
− | + | ;;; printByte: prints 1 byte of secret msg | |
− | + | ;;; registers modified: edx, ecx, eax, ebx | |
− | + | ;;; written by: Ellysha Raelen Recto | |
− | + | ;;; ------------------------------------------------------------- | |
− | ; | + | printByte: |
− | + | pushad ; pushes registers to stack | |
− | mov | + | mov byte[msg], dl ; moves byte read from image to msg |
− | + | mov eax, SYS_WRITE | |
− | + | mov ebx, STDOUT | |
− | + | mov ecx, msg ; prints msg | |
− | + | mov edx, 1 | |
− | + | int 0x80 | |
+ | popad ; retrieves values of registers from stack | ||
+ | ret | ||
− | mov | + | ;;; ------------------------------------------------------------- |
− | and | + | ;;; read1bit: used to read a bit if it's one of the first 7 bits of |
− | or | + | ;;; a byte from the image |
− | + | ;;; registers modified: edx, eax | |
+ | ;;; written by: Ellysha Raelen Recto | ||
+ | ;;; ------------------------------------------------------------- | ||
+ | read1bit: | ||
+ | mov al, byte[ebx+pixelBuf+7] | ||
+ | and al, 1 ; get the last bit of byte from image | ||
+ | or dl, al ; saves the values of the bits from | ||
+ | ; the bytes of already read to dl | ||
+ | shl dl, 1 ; shifts bits to make room for next bit | ||
+ | ; to be read | ||
+ | ret | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</pre></code> | </pre></code> |
Revision as of 17:11, 4 November 2008
;;; hw6.asm
;;; Ellysha Raelen Recto
;;;
;;; This program written from the skeleton program, makegreyBmp.asm, written
;;; by D. Thiebaut. This program reads a bmp file and reads the last bit of
;;; each byte. The bytes read contains a secret msg which is then displayed.
;;;
%include "mytools2.inc" ; for basic printing to the screen
%include "fileio2.inc" ; for basic file operations
%assign SYS_EXIT 1
%assign MAXPIXEL 5000000
%assign SYS_WRITE 4
%assign STDOUT 1
%assign RED 2
%assign GREEN 1
%assign BLUE 0
;;; ---------------------------------------------------------
;;; data segments
;;; ---------------------------------------------------------
section .data
errorMsg db "Error accessing file!",0x0A
errorLen equ $-errorMsg
msg db 0
section .bss
filename resb 255 ; reserve 255 chars for filename
handle resd 1 ; file descriptor
noRead resd 1 ; contains number of bytes read
lWidth resd 1 ; the line width rounded to the nearest
; dword boundary lWidth=(((width-1)/4)+1)*4
;;; ----------------------------------------------------------
;;; bmp buffer starts here
;;; ----------------------------------------------------------
bmpBuf equ $
type resw 1 ; header
size resd 1
resvd1 resw 1
resvd2 resw 1
offset resd 1
;;;
size2 resd 1 ; information header
width resd 1
height resd 1
planes resw 1
xbits resw 1
compr resd 1
imgsize resd 1
xres resd 1
yres resd 1
nocol resd 1
impcol resd 1
headLen equ $-bmpBuf ; length of header
pixelBuf resb MAXPIXEL*3 ; times 3 bytes (RGB)
;;; ---------------------------------------------------------
;;; code area
;;; ---------------------------------------------------------
section .text
global _start
_start:
;;; --- check that user entered more than 1 argument on command line ---
pop ebx ; get # of arguments on command line
cmp ebx,1
jg process ; if user forgot file name, exit
dumpStr "Syntax: progName filename"
jmp exit
;;; --- get filename from command line ---
process:
pop ebx ; pointer to argv[0] (name of program)
pop ebx ; pointer to argv[1]
mov edi,filename ; pointer to filename
copy: mov al,[ebx] ; copy name of file from argv[1] to
mov [edi],al ; filename string, until \0 is copied
inc ebx
inc edi
cmp al,0
jne copy
;;; --- open file ---
openFile filename, [handle], errorMsg, errorLen
;;; --- read file in buffer ---
readFile [handle], bmpBuf, MAXPIXEL, noRead
;;; --- compute length of a line of pixel:
;;; line length = (( byte width+3)/4)*4 where
;;; byte width = 3 * width, since we have 3 bytes per pixel
;;;
mov eax,[width]
add eax,[width]
add eax,[width] ; eax <-- 3 x width
dec eax ; eax
shr eax,2 ;
inc eax
shl eax,2
mov [lWidth],eax
;;; --------------------------------------------------------------
;;; Find the address of the first byte of the image and put
;;; it in ebx
;;; --------------------------------------------------------------
mov eax,0
push eax
push eax
call hw2index
;; -----------------------------------
;; add your byte-examining loop below!
;; you can access the bytes of the pixels as byte[ebx+pixelBuf]
;; and increment ebx in the loop to access successive bytes
;; -----------------------------------
;; -----------------------------------
;; mainFor: main section for reading secret bytes
;; written by: Ellysha Raelen Recto
;; registers modified: none
;; -----------------------------------
mainFor:
call decode1byte ; calls method to decode 1 byte of secret msg
cmp dl, 0 ; if 1 byte is zero, end of secret msg
je exit ; go to exit if end of msg is found
call printByte ; print byte
jmp mainFor ; decode more bytes if end of msg isnt found
;; -----------------------------------
;; end of pixel loop area
;; -----------------------------------
;;; --- position file pointer back to beginning of file ---
seek0 [handle]
;;; --- write contents back to file ---
writeBuf [handle], bmpBuf, noRead
;;; --- close file ---
close [handle]
;;; --- exit() ---
exit:
mov eax,SYS_EXIT
mov ebx,0
int 0x80 ; final system call
;;; -------------------------------------------------------------
;;; hw2index: converts height and width to pixel index
;;; index returned in ebx. Note that computation is
;;; performed with lWidth which must be computed
;;; separately and is the number of bytes in one line
;;; of pixel, such that number of byte is a multiple of
;;; 4.
;;; registers modified: ebx
;;; -------------------------------------------------------------
hw2index:
push ebp
mov ebp,esp
push eax ; save eax and edx
push edx
mov eax,[lWidth]
xor edx,edx
mul dword[ebp+12] ; eax = lWidth * h
add eax,[ebp+8] ; eax += 3*w
add eax,[ebp+8]
add eax,[ebp+8]
mov ebx,eax ; pass result in ebx
pop edx
pop eax
pop ebp
ret 8
;;; -------------------------------------------------------------
;;; decode1byte: decodes 1 byte of secret msg, first bit of the byte
;;; is from the last bit of first 8th byte of image
;;; registers modified: edx, ecx, eax, ebx
;;; written by: Ellysha Raelen Recto
;;; -------------------------------------------------------------
decode1byte:
mov dl, 0
mov ecx,7 ; reads first 7 bits
for: call read1bit ; call method to read 1 bit with shifting
dec ebx ; goes to next bit
loop for
mov al, byte[ebx+pixelBuf+7] ; reads last bit
and al, 1
or dl, al
add ebx, 15
ret
;;; -------------------------------------------------------------
;;; printByte: prints 1 byte of secret msg
;;; registers modified: edx, ecx, eax, ebx
;;; written by: Ellysha Raelen Recto
;;; -------------------------------------------------------------
printByte:
pushad ; pushes registers to stack
mov byte[msg], dl ; moves byte read from image to msg
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg ; prints msg
mov edx, 1
int 0x80
popad ; retrieves values of registers from stack
ret
;;; -------------------------------------------------------------
;;; read1bit: used to read a bit if it's one of the first 7 bits of
;;; a byte from the image
;;; registers modified: edx, eax
;;; written by: Ellysha Raelen Recto
;;; -------------------------------------------------------------
read1bit:
mov al, byte[ebx+pixelBuf+7]
and al, 1 ; get the last bit of byte from image
or dl, al ; saves the values of the bits from
; the bytes of already read to dl
shl dl, 1 ; shifts bits to make room for next bit
; to be read
ret