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

  1. ; IMGPRCS.ASM
  2. ;
  3. ; An image processing program (Second 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. ;
  14. ; Version #2: Three major optimizations. (1) used movsd instruction rather
  15. ;          than a loop to copy data from DataOut back to DataIn.
  16. ;          (2) Used repeat..until forms for all loops.  (3) unrolled
  17. ;          the innermost two loops (which is responsible for most of
  18. ;          the performance improvement).
  19. ;
  20. ; Version #3: Used registers for all variables. Set up segment registers
  21. ;          once and for all through the execution of the main loop so
  22. ;          the code didn't have to reload ds each time through.  Computed
  23. ;          index into each row only once (outside the j loop).
  24. ;
  25. ; Version #4: Eliminated copying data from DataOut to DataIn on each pass.
  26. ;          Removed hazards.  Maintained common subexpressions. Did some
  27. ;          more loop unrolling.
  28. ;
  29. ; Version #5: Converted data arrays to words rather than bytes and operated
  30. ;          on 16-bit values.  Yielded minimal speedup.
  31. ;
  32. ;    Performance comparisons (66 MHz 80486 DX/2 system).
  33. ;
  34. ;    This code-           2.4 seconds.
  35. ;    3rd optimization pass- 2.5 seconds.
  36. ;    2nd optimization pass-     4 seconds.
  37. ;    1st optimization pass-     6 seconds.
  38. ;    Original ASM code-    36 seconds.
  39. ;    Borland Pascal v7.0-    45 seconds.
  40. ;    Borland C++ v4.02-    29 seconds.
  41. ;    Microsoft C++ v8.00-    21 seconds.
  42.  
  43.         .xlist
  44.         include     stdlib.a
  45.         includelib    stdlib.lib
  46.         .list
  47.         .386
  48.         option        segment:use16
  49.  
  50.  
  51.  
  52. dseg        segment    para public 'data'
  53.  
  54. ImgData        byte    251 dup (256 dup (?))
  55.  
  56. InName        byte    "roller1.raw",0
  57. OutName        byte    "roller2.raw",0
  58. Iterations    word    0
  59.  
  60. dseg        ends
  61.  
  62.  
  63. ; This code makes the naughty assumption that the following
  64. ; segments are loaded contiguously in memory!  Also, because these
  65. ; segments are paragraph aligned, this code assumes that these segments
  66. ; will contain a full 65,536 bytes.  You cannot declare a segment with
  67. ; exactly 65,536 bytes in MASM.  However, the paragraph alignment option
  68. ; ensures that the extra byte of padding is added to the end of each
  69. ; segment.
  70.  
  71. DataSeg1    segment    para public 'ds1'
  72. Data1a        byte    65535 dup (?)
  73. DataSeg1    ends
  74.  
  75. DataSeg2    segment    para public 'ds2'
  76. Data1b        byte    65535 dup (?)
  77. DataSeg2    ends
  78.  
  79. DataSeg3    segment    para public 'ds3'
  80. Data2a        byte    65535 dup (?)
  81. DataSeg3    ends
  82.  
  83. DataSeg4    segment    para public 'ds4'
  84. Data2b        byte    65535 dup (?)
  85. DataSeg4    ends
  86.  
  87.  
  88.  
  89.  
  90. cseg        segment    para public 'code'
  91.         assume    cs:cseg, ds:dseg
  92.  
  93. Main        proc
  94.         mov    ax, dseg
  95.         mov    ds, ax
  96.         meminit
  97.  
  98.         mov    ax, 3d00h    ;Open input file for reading.
  99.         lea    dx, InName
  100.         int    21h
  101.         jnc    GoodOpen
  102.         print
  103.         byte    "Could not open input file.",cr,lf,0
  104.         jmp    Quit
  105.  
  106. ; Optimization modification- read the data into DataOut rather than
  107. ; DataIn because we'll move it into DataIn at the beginning of the
  108. ; hloop.
  109.  
  110. GoodOpen:    mov    bx, ax        ;File handle.
  111.         lea    dx, ImgData
  112.         mov    cx, 256*251    ;Size of data file to read.
  113.         mov    ah, 3Fh
  114.         int    21h
  115.         cmp    ax, 256*251    ;See if we read the data.
  116.         je    GoodRead
  117.         print
  118.         byte    "Did not read the file properly",cr,lf,0
  119.         jmp    Quit
  120.  
  121. GoodRead:       print
  122.         byte    "Enter number of iterations: ",0
  123.         getsm
  124.         atoi
  125.         free
  126.         mov    Iterations, ax
  127.         cmp    ax, 0
  128.         jle    Quit
  129.  
  130.         printf
  131.         byte    "Computing Result for %d iterations",cr,lf,0
  132.         dword    Iterations
  133.  
  134.  
  135.  
  136. ; Copy the data and expand it from eight bits to sixteen bits.
  137. ; The first loop handles the first 32,768 bytes, the second loop
  138. ; handles the remaining bytes.
  139.  
  140.         mov    ax, DataSeg1
  141.         mov    es, ax
  142.         mov    ax, DataSeg3
  143.         mov    fs, ax
  144.  
  145.         mov    ah, 0
  146.         mov    cx, 32768
  147.         lea    si, ImgData
  148.         xor    di, di            ;Output data is at ofs zero.
  149. CopyLoop:    lodsb
  150.         mov    fs:[di], ax
  151.         stosw
  152.         dec    cx
  153.         jne    CopyLoop
  154.  
  155.         mov    di, DataSeg2
  156.         mov    es, di
  157.         mov    di, DataSeg4
  158.         mov    fs, di
  159.         mov    cx, (251*256) - 32768
  160.         xor    di, di
  161. CopyLoop1:    lodsb
  162.         mov    fs:[di], ax
  163.         stosw
  164.         dec    cx
  165.         jne    CopyLoop1
  166.  
  167. ; hloop completes one iteration on the data moving it from Data1a/Data1b
  168. ; to Data2a/Data2b
  169.  
  170. hloop:        mov    ax, DataSeg1
  171.         mov    ds, ax
  172.         mov    ax, DataSeg3
  173.         mov    es, ax
  174.  
  175. ; Process the first 127 rows (65,024 bytes) of the array):
  176.  
  177.         mov    cl, 127
  178.         lea    si, Data1a+202h        ;Start at [1,1]
  179. iloop0:        mov    ch, 254/2        ;# of times through loop.
  180. jloop0:        mov    dx, [si]        ;[i,j]
  181.         mov    bx, [si-200h]        ;[i-1,j]
  182.         mov    ax, dx
  183.         shl    dx, 3            ;[i,j] * 8
  184.         add    bx, [si-1feh]        ;[i-1,j+1]
  185.         mov    bp, [si+2]        ;[i,j+1]
  186.         add    bx, [si+200h]        ;[i+1,j]
  187.         add    dx, bp
  188.         add    bx, [si+202h]        ;[i+1,j+1]
  189.         add    dx, [si-202h]        ;[i-1,j-1]
  190.         mov    di, [si-1fch]        ;[i-1,j+2]
  191.         add    dx, [si-2]        ;[i,j-1]
  192.         add    di, [si+4]        ;[i,j+2]
  193.         add    dx, [si+1feh]        ;[i+1,j-1]
  194.         add    di, [si+204h]        ;[i+1,j+2]
  195.         shl    bp, 3            ;[i,j+1] * 8
  196.         add    dx, bx
  197.         add    bp, ax
  198.         shr    dx, 4            ;Divide by 16.
  199.         add    bp, bx
  200.         mov    es:[si], dx        ;Store [i,j] entry.
  201.         add    bp, di
  202.         add    si, 4            ;Affects next store operation!
  203.         shr    bp, 4            ;Divide by 16.
  204.         dec    ch
  205.         mov    es:[si-2], bp        ;Store [i,j+1] entry.
  206.         jne    jloop0
  207.  
  208.         add    si, 4            ;Skip to start of next row.
  209.  
  210.         dec    cl
  211.         jne    iloop0
  212.  
  213. ; Process the last 124 rows of the array).  This requires that we switch from
  214. ; one segment to the next.  Note that the segments overlap.
  215.  
  216.         mov    ax, DataSeg2
  217.         sub    ax, 40h            ;Back up to last 2 rows in DS2
  218.         mov    ds, ax
  219.         mov    ax, DataSeg4
  220.         sub    ax, 40h            ;Back up to last 2 rows in DS4
  221.         mov    es, ax
  222.  
  223.         mov    cl, 251-127-1        ;Remaining rows to process.
  224.         mov    si, 202h        ;Continue with next row.
  225. iloop1:        mov    ch, 254/2        ;# of times through loop.
  226. jloop1:        mov    dx, [si]        ;[i,j]
  227.         mov    bx, [si-200h]        ;[i-1,j]
  228.         mov    ax, dx
  229.         shl    dx, 3            ;[i,j] * 8
  230.         add    bx, [si-1feh]        ;[i-1,j+1]
  231.         mov    bp, [si+2]        ;[i,j+1]
  232.         add    bx, [si+200h]        ;[i+1,j]
  233.         add    dx, bp
  234.         add    bx, [si+202h]        ;[i+1,j+1]
  235.         add    dx, [si-202h]        ;[i-1,j-1]
  236.         mov    di, [si-1fch]        ;[i-1,j+2]
  237.         add    dx, [si-2]        ;[i,j-1]
  238.         add    di, [si+4]        ;[i,j+2]
  239.         add    dx, [si+1feh]        ;[i+1,j-1]
  240.         add    di, [si+204h]        ;[i+1,j+2]
  241.         shl    bp, 3            ;[i,j+1] * 8
  242.         add    dx, bx
  243.         add    bp, ax
  244.         shr    dx, 4            ;Divide by 16
  245.         add    bp, bx
  246.         mov    es:[si], dx        ;Store [i,j] entry.
  247.         add    bp, di
  248.         add    si, 4            ;Affects next store operation!
  249.         shr    bp, 4
  250.         dec    ch
  251.         mov    es:[si-2], bp        ;Store [i,j+1] entry.
  252.         jne    jloop1
  253.  
  254.         add    si, 4            ;Skip to start of next row.
  255.  
  256.         dec    cl
  257.         jne    iloop1
  258.  
  259.         mov    ax, dseg
  260.         mov    ds, ax
  261.         assume    ds:dseg
  262.  
  263.         dec    Iterations
  264.         je    Done0
  265.  
  266. ; Unroll the iterations loop so we can move the data from DataSeg2/4 back
  267. ; to DataSeg1/3 without wasting extra time.  Other than the direction of the
  268. ; data movement, this code is virtually identical to the above.
  269.  
  270.         mov    ax, DataSeg3
  271.         mov    ds, ax
  272.         mov    ax, DataSeg1
  273.         mov    es, ax
  274.  
  275.         mov    cl, 127
  276.         lea    si, Data1a+202h
  277. iloop2:        mov    ch, 254/2
  278. jloop2:        mov    dx, [si]
  279.         mov    bx, [si-200h]
  280.         mov    ax, dx
  281.         shl    dx, 3
  282.         add    bx, [si-1feh]
  283.         mov    bp, [si+2]
  284.         add    bx, [si+200h]
  285.         add    dx, bp
  286.         add    bx, [si+202h]
  287.         add    dx, [si-202h]
  288.         mov    di, [si-1fch]
  289.         add    dx, [si-2]
  290.         add    di, [si+4]
  291.         add    dx, [si+1feh]
  292.         add    di, [si+204h]
  293.         shl    bp, 3
  294.         add    dx, bx
  295.         add    bp, ax
  296.         shr    dx, 4
  297.         add    bp, bx
  298.         mov    es:[si], dx
  299.         add    bp, di
  300.         add    si, 4
  301.         shr    bp, 4
  302.         dec    ch
  303.         mov    es:[si-2], bp
  304.         jne    jloop2
  305.  
  306.         add    si, 4
  307.  
  308.         dec    cl
  309.         jne    iloop2
  310.  
  311.  
  312.         mov    ax, DataSeg4
  313.         sub    ax, 40h
  314.         mov    ds, ax
  315.         mov    ax, DataSeg2
  316.         sub    ax, 40h
  317.         mov    es, ax
  318.  
  319.         mov    cl, 251-127-1
  320.         mov    si, 202h
  321. iloop3:        mov    ch, 254/2
  322. jloop3:        mov    dx, [si]
  323.         mov    bx, [si-200h]
  324.         mov    ax, dx
  325.         shl    dx, 3
  326.         add    bx, [si-1feh]
  327.         mov    bp, [si+2]
  328.         add    bx, [si+200h]
  329.         add    dx, bp
  330.         add    bx, [si+202h]
  331.         add    dx, [si-202h]
  332.         mov    di, [si-1fch]
  333.         add    dx, [si-2]
  334.         add    di, [si+4]
  335.         add    dx, [si+1feh]
  336.         add    di, [si+204h]
  337.         shl    bp, 3
  338.         add    dx, bx
  339.         add    bp, ax
  340.         shr    dx, 4
  341.         add    bp, bx
  342.         mov    es:[si], dx
  343.         add    bp, di
  344.         add    si, 4
  345.         shr    bp, 4
  346.         dec    ch
  347.         mov    es:[si-2], bp
  348.         jne    jloop3
  349.  
  350.         add    si, 4
  351.  
  352.         dec    cl
  353.         jne    iloop3
  354.  
  355.         mov    ax, dseg
  356.         mov    ds, ax
  357.         assume    ds:dseg
  358.  
  359.         dec    Iterations
  360.         je    Done2
  361.         jmp    hloop
  362.  
  363. Done2:        mov    ax, DataSeg1
  364.         mov    bx, DataSeg2
  365.         jmp    Finish
  366.  
  367. Done0:        mov    ax, DataSeg3
  368.         mov    bx, DataSeg4
  369. Finish:        mov    ds, ax
  370.         print
  371.         byte    "Writing result",cr,lf,0
  372.  
  373. ; Convert data back to byte form and write to the output file:
  374.  
  375.         mov    ax, dseg
  376.         mov    es, ax
  377.  
  378.         mov    cx, 32768
  379.         lea    di, ImgData
  380.         xor    si, si            ;Output data is at ofs zero.
  381. CopyLoop3:    lodsw
  382.         stosb
  383.         dec    cx
  384.         jne    CopyLoop3
  385.  
  386.         mov    ds, bx
  387.         mov    cx, (251*256) - 32768
  388.         xor    si, si
  389. CopyLoop4:    lodsw
  390.         stosb
  391.         dec    cx
  392.         jne    CopyLoop4
  393.  
  394.  
  395. ; Okay, write the data to the output file:
  396.  
  397.         mov    ah, 3ch        ;Create output file.
  398.         mov    cx, 0        ;Normal file attributes.
  399.         mov    dx, dseg
  400.         mov    ds, dx
  401.         lea    dx, OutName
  402.         int    21h
  403.         jnc    GoodCreate
  404.         print
  405.         byte    "Could not create output file.",cr,lf,0
  406.         jmp    Quit
  407.  
  408. GoodCreate:    mov    bx, ax        ;File handle.
  409.         push    bx
  410.         mov    dx, dseg    ;Where the data can be found.
  411.         mov    ds, dx
  412.         lea    dx, ImgData
  413.         mov    cx, 256*251    ;Size of data file to write.
  414.         mov    ah, 40h        ;Write operation.
  415.         int    21h
  416.         pop    bx        ;Retrieve handle for close.
  417.         cmp    ax, 256*251    ;See if we wrote the data.
  418.         je    GoodWrite
  419.         print
  420.         byte    "Did not write the file properly",cr,lf,0
  421.         jmp    Quit
  422.  
  423. GoodWrite:    mov    ah, 3eh        ;Close operation.
  424.         int    21h
  425.  
  426.  
  427. Quit:        ExitPgm            ;DOS macro to quit program.
  428. Main        endp
  429.  
  430. cseg        ends
  431.  
  432. sseg        segment    para stack 'stack'
  433. stk        byte    1024 dup ("stack   ")
  434. sseg        ends
  435.  
  436. zzzzzzseg    segment    para public 'zzzzzz'
  437. LastBytes    byte    16 dup (?)
  438. zzzzzzseg    ends
  439.         end    Main
  440.