home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH25 / IMGPRCS2.ASM < prev    next >
Encoding:
Assembly Source File  |  1994-08-05  |  5.1 KB  |  252 lines

  1. ; IMGPRCS2.ASM
  2. ;
  3. ; An image processing program (First optimization pass).
  4. ;
  5. ; This program blurs an eight-bit grayscale image by averaging a pixel
  6. ; in the image with the eight pixels around it.  The average is computed
  7. ; by (CurCell*8 + other 8 cells)/16, weighting the current cell by 50%.
  8. ;
  9. ; Because of the size of the image (almost 64K), the input and output
  10. ; matrices are in different segments.
  11. ;
  12. ; Version #1: Straight-forward translation from Pascal to Assembly.
  13. ; Version #2: Three major optimizations. (1) used movsd instruction rather
  14. ;          than a loop to copy data from DataOut back to DataIn.
  15. ;          (2) Used repeat..until forms for all loops.  (3) unrolled
  16. ;          the innermost two loops (which is responsible for most of
  17. ;          the performance improvement).
  18. ;
  19. ;
  20. ;    Performance comparisons (66 MHz 80486 DX/2 system).
  21. ;
  22. ;    This code-         6 seconds.
  23. ;    Original ASM code-    36 seconds.
  24. ;    Borland Pascal v7.0-    45 seconds.
  25. ;    Borland C++ v4.02-    29 seconds.
  26. ;    Microsoft C++ v8.00-    21 seconds.
  27.  
  28.         .xlist
  29.         include     stdlib.a
  30.         includelib    stdlib.lib
  31.         .list
  32.         .386
  33.         option        segment:use16
  34.  
  35. dseg        segment    para public 'data'
  36.  
  37. ; Loop control variables and other variables:
  38.  
  39. h        word    ?
  40. i        word    ?
  41. j        word    ?
  42. k        word    ?
  43. l        word    ?
  44. sum        word    ?
  45. iterations    word    ?
  46.  
  47. ; File names:
  48.  
  49. InName        byte    "roller1.raw",0
  50. OutName        byte    "roller2.raw",0
  51.  
  52. dseg        ends
  53.  
  54.  
  55. ; Here is the input data that we operate on.
  56.  
  57. InSeg        segment    para public 'indata'
  58.  
  59. DataIn        byte    251 dup (256 dup (?))
  60.  
  61. InSeg        ends
  62.  
  63.  
  64. ; Here is the output array that holds the result.
  65.  
  66. OutSeg        segment    para public 'outdata'
  67.  
  68. DataOut        byte    251 dup (256 dup (?))
  69.  
  70. OutSeg        ends
  71.  
  72.  
  73.  
  74.  
  75. cseg        segment    para public 'code'
  76.         assume    cs:cseg, ds:dseg
  77.  
  78. Main        proc
  79.         mov    ax, dseg
  80.         mov    ds, ax
  81.         meminit
  82.  
  83.         mov    ax, 3d00h    ;Open input file for reading.
  84.         lea    dx, InName
  85.         int    21h
  86.         jnc    GoodOpen
  87.         print
  88.         byte    "Could not open input file.",cr,lf,0
  89.         jmp    Quit
  90.  
  91. ; Optimization modification- read the data into DataOut rather than
  92. ; DataIn because we'll move it into DataIn at the beginning of the
  93. ; h loop.
  94.  
  95. GoodOpen:    mov    bx, ax        ;File handle.
  96.         mov    dx, OutSeg    ;Where to put the data.
  97.         mov    ds, dx
  98.         lea    dx, DataOut
  99.         mov    cx, 256*251    ;Size of data file to read.
  100.         mov    ah, 3Fh
  101.         int    21h
  102.         cmp    ax, 256*251    ;See if we read the data.
  103.         je    GoodRead
  104.         print
  105.         byte    "Did not read the file properly",cr,lf,0
  106.         jmp    Quit
  107.  
  108. GoodRead:       mov    ax, dseg
  109.         mov    ds, ax
  110.         print
  111.         byte    "Enter number of iterations: ",0
  112.         getsm
  113.         atoi
  114.         free
  115.         mov    iterations, ax
  116.         cmp    ax, 0
  117.         jle    Quit
  118.  
  119.         print
  120.         byte    "Computing Result",cr,lf,0
  121.  
  122. ; for h := 1 to iterations-
  123.  
  124.         mov    h, 1
  125. hloop:
  126.  
  127. ; Copy the input data to the output buffer.
  128. ; Optimization step #1: Replace with movs instruction.
  129.  
  130.         push    ds
  131.         mov    ax, OutSeg
  132.         mov    ds, ax
  133.         mov    ax, InSeg
  134.         mov    es, ax
  135.         lea    si, DataOut
  136.         lea    di, DataIn
  137.         mov    cx, (251*256)/4
  138.     rep    movsd
  139.         pop    ds
  140.  
  141.  
  142. ; Optimization Step #1: Convert loops to repeat..until form.
  143.  
  144. ; for i := 1 to 249 -
  145.  
  146.         mov    i, 1
  147. iloop:
  148.  
  149. ; for j := 1 to 254 -
  150.  
  151.         mov    j, 1
  152. jloop:
  153.  
  154.  
  155. ; Optimization.  Unroll the innermost two loops:
  156.  
  157.         mov    bh, byte ptr i        ;i is always less than 256.
  158.         mov    bl, byte ptr j        ;Computes i*256+j!
  159.  
  160.         push    ds
  161.         mov    ax, InSeg        ;Gain access to InSeg.
  162.         mov    ds, ax
  163.  
  164.         mov    cx, 0            ;Compute sum here.
  165.         mov    ah, ch
  166.         mov    cl, ds:DataIn[bx-257]    ;DataIn[i-1][j-1]
  167.         mov    al, ds:DataIn[bx-256]    ;DataIn[i-1][j]
  168.         add    cx, ax
  169.         mov    al, ds:DataIn[bx-255]    ;DataIn[i-1][j+1]
  170.         add    cx, ax
  171.         mov    al, ds:DataIn[bx-1]    ;DataIn[i][j-1]
  172.         add    cx, ax
  173.         mov    al, ds:DataIn[bx+1]    ;DataIn[i][j+1]
  174.         add    cx, ax
  175.         mov    al, ds:DataIn[bx+255]    ;DataIn[i+1][j-1]
  176.         add    cx, ax
  177.         mov    al, ds:DataIn[bx+256]    ;DataIn[i+1][j]
  178.         add    cx, ax
  179.         mov    al, ds:DataIn[bx+257]    ;DataIn[i+1][j+1]
  180.         add    cx, ax
  181.  
  182.         mov    al, ds:DataIn[bx]    ;DataIn[i][j]
  183.         shl    ax, 3            ;DataIn[i][j]*8
  184.         add    cx, ax
  185.         shr    cx, 4            ;Divide by 16
  186.         mov    ax, OutSeg
  187.         mov    ds, ax
  188.         mov    ds:DataOut[bx], cl
  189.         pop    ds
  190.  
  191.         inc    j
  192.         cmp    j, 254
  193.         jbe    jloop
  194.  
  195.         inc    i
  196.         cmp    i, 249
  197.         jbe    iloop
  198.  
  199.         inc    h
  200.         mov    ax, h
  201.         cmp    ax, Iterations
  202.         jnbe    Done
  203.         jmp    hloop
  204.  
  205. Done:        print
  206.         byte    "Writing result",cr,lf,0
  207.  
  208.  
  209. ; Okay, write the data to the output file:
  210.  
  211.         mov    ah, 3ch        ;Create output file.
  212.         mov    cx, 0        ;Normal file attributes.
  213.         lea    dx, OutName
  214.         int    21h
  215.         jnc    GoodCreate
  216.         print
  217.         byte    "Could not create output file.",cr,lf,0
  218.         jmp    Quit
  219.  
  220. GoodCreate:    mov    bx, ax        ;File handle.
  221.         push    bx
  222.         mov    dx, OutSeg    ;Where the data can be found.
  223.         mov    ds, dx
  224.         lea    dx, DataOut
  225.         mov    cx, 256*251    ;Size of data file to write.
  226.         mov    ah, 40h        ;Write operation.
  227.         int    21h
  228.         pop    bx        ;Retrieve handle for close.
  229.         cmp    ax, 256*251    ;See if we wrote the data.
  230.         je    GoodWrite
  231.         print
  232.         byte    "Did not write the file properly",cr,lf,0
  233.         jmp    Quit
  234.  
  235. GoodWrite:    mov    ah, 3eh        ;Close operation.
  236.         int    21h
  237.  
  238.  
  239. Quit:        ExitPgm            ;DOS macro to quit program.
  240. Main        endp
  241.  
  242. cseg        ends
  243.  
  244. sseg        segment    para stack 'stack'
  245. stk        byte    1024 dup ("stack   ")
  246. sseg        ends
  247.  
  248. zzzzzzseg    segment    para public 'zzzzzz'
  249. LastBytes    byte    16 dup (?)
  250. zzzzzzseg    ends
  251.         end    Main
  252.