home *** CD-ROM | disk | FTP | other *** search
- ; IMGPRCS.ASM
- ;
- ; An image processing program (Second optimization pass).
- ;
- ; This program blurs an eight-bit grayscale image by averaging a pixel
- ; in the image with the eight pixels around it. The average is computed
- ; by (CurCell*8 + other 8 cells)/16, weighting the current cell by 50%.
- ;
- ; Because of the size of the image (almost 64K), the input and output
- ; matrices are in different segments.
- ;
- ; Version #1: Straight-forward translation from Pascal to Assembly.
- ; Version #2: Three major optimizations. (1) used movsd instruction rather
- ; than a loop to copy data from DataOut back to DataIn.
- ; (2) Used repeat..until forms for all loops. (3) unrolled
- ; the innermost two loops (which is responsible for most of
- ; the performance improvement).
- ; Version #3: Used registers for all variables. Set up segment registers
- ; once and for all through the execution of the main loop so
- ; the code didn't have to reload ds each time through. Computed
- ; index into each row only once (outside the j loop).
- ;
- ;
- ; Performance comparisons (66 MHz 80486 DX/2 system).
- ;
- ; This code- 4 seconds.
- ; 1st optimization pass- 6 seconds.
- ; Original ASM code- 36 seconds.
- ; Borland Pascal v7.0- 45 seconds.
- ; Borland C++ v4.02- 29 seconds.
- ; Microsoft C++ v8.00- 21 seconds.
-
- .xlist
- include stdlib.a
- includelib stdlib.lib
- .list
- .386
- option segment:use16
-
-
-
- dseg segment para public 'data'
- InName byte "roller1.raw",0
- OutName byte "roller2.raw",0
- dseg ends
-
-
- ; Here is the input data that we operate on.
-
- InSeg segment para public 'indata'
-
- DataIn byte 251 dup (256 dup (?))
-
- InSeg ends
-
-
- ; Here is the output array that holds the result.
-
- OutSeg segment para public 'outdata'
-
- DataOut byte 251 dup (256 dup (?))
-
- OutSeg ends
-
-
-
-
- cseg segment para public 'code'
- assume cs:cseg, ds:dseg
-
- Main proc
- mov ax, dseg
- mov ds, ax
- meminit
-
- mov ax, 3d00h ;Open input file for reading.
- lea dx, InName
- int 21h
- jnc GoodOpen
- print
- byte "Could not open input file.",cr,lf,0
- jmp Quit
-
- ; Optimization modification- read the data into DataOut rather than
- ; DataIn because we'll move it into DataIn at the beginning of the
- ; h loop.
-
- GoodOpen: mov bx, ax ;File handle.
- mov dx, OutSeg ;Where to put the data.
- mov ds, dx
- lea dx, DataOut
- mov cx, 256*251 ;Size of data file to read.
- mov ah, 3Fh
- int 21h
- cmp ax, 256*251 ;See if we read the data.
- je GoodRead
- print
- byte "Did not read the file properly",cr,lf,0
- jmp Quit
-
- GoodRead: print
- byte "Enter number of iterations: ",0
- getsm
- atoi
- free
- mov bp, ax
- cmp ax, 0
- jle Quit
-
- print
- byte "Computing Result",cr,lf,0
-
-
- ; Copy the input data to the output buffer.
-
-
- hloop: mov ax, InSeg
- mov es, ax
- mov ax, OutSeg
- mov ds, ax
- lea si, DataOut
- lea di, DataIn
- mov cx, (251*256)/4
- rep movsd
-
- assume ds:InSeg, es:OutSeg
- mov ax, InSeg
- mov ds, ax
- mov ax, OutSeg
- mov es, ax
-
-
-
- mov cl, 249
- iloop: mov bh, cl ;i*256
- mov bl, 1 ;Start at j=1.
- mov ch, 254 ;# of times through loop.
- jloop:
- mov dx, 0 ;Compute sum here.
- mov ah, dh
- mov dl, DataIn[bx-257] ;DataIn[i-1][j-1]
- mov al, DataIn[bx-256] ;DataIn[i-1][j]
- add dx, ax
- mov al, DataIn[bx-255] ;DataIn[i-1][j+1]
- add dx, ax
- mov al, DataIn[bx-1] ;DataIn[i][j-1]
- add dx, ax
- mov al, DataIn[bx+1] ;DataIn[i][j+1]
- add dx, ax
- mov al, DataIn[bx+255] ;DataIn[i+1][j-1]
- add dx, ax
- mov al, DataIn[bx+256] ;DataIn[i+1][j]
- add dx, ax
- mov al, DataIn[bx+257] ;DataIn[i+1][j+1]
- add dx, ax
-
- mov al, DataIn[bx] ;DataIn[i][j]
- shl ax, 3 ;DataIn[i][j]*8
- add dx, ax
- shr dx, 4 ;Divide by 16
- mov DataOut[bx], dl
-
- inc bx
- dec ch
- jne jloop
-
- dec cl
- jne iloop
-
- dec bp
- jne hloop
-
- Done: print
- byte "Writing result",cr,lf,0
-
-
- ; Okay, write the data to the output file:
-
- mov ah, 3ch ;Create output file.
- mov cx, 0 ;Normal file attributes.
- mov dx, dseg
- mov ds, dx
- lea dx, OutName
- int 21h
- jnc GoodCreate
- print
- byte "Could not create output file.",cr,lf,0
- jmp Quit
-
- GoodCreate: mov bx, ax ;File handle.
- push bx
- mov dx, OutSeg ;Where the data can be found.
- mov ds, dx
- lea dx, DataOut
- mov cx, 256*251 ;Size of data file to write.
- mov ah, 40h ;Write operation.
- int 21h
- pop bx ;Retrieve handle for close.
- cmp ax, 256*251 ;See if we wrote the data.
- je GoodWrite
- print
- byte "Did not write the file properly",cr,lf,0
- jmp Quit
-
- GoodWrite: mov ah, 3eh ;Close operation.
- int 21h
-
-
- Quit: ExitPgm ;DOS macro to quit program.
- Main endp
-
- cseg ends
-
- sseg segment para stack 'stack'
- stk byte 1024 dup ("stack ")
- sseg ends
-
- zzzzzzseg segment para public 'zzzzzz'
- LastBytes byte 16 dup (?)
- zzzzzzseg ends
- end Main
-