📄 imgprcs2.asm
字号:
; IMGPRCS2.ASM
;
; An image processing program (First 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).
;
;
; Performance comparisons (66 MHz 80486 DX/2 system).
;
; This code- 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'
; Loop control variables and other variables:
h word ?
i word ?
j word ?
k word ?
l word ?
sum word ?
iterations word ?
; File names:
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: mov ax, dseg
mov ds, ax
print
byte "Enter number of iterations: ",0
getsm
atoi
free
mov iterations, ax
cmp ax, 0
jle Quit
print
byte "Computing Result",cr,lf,0
; for h := 1 to iterations-
mov h, 1
hloop:
; Copy the input data to the output buffer.
; Optimization step #1: Replace with movs instruction.
push ds
mov ax, OutSeg
mov ds, ax
mov ax, InSeg
mov es, ax
lea si, DataOut
lea di, DataIn
mov cx, (251*256)/4
rep movsd
pop ds
; Optimization Step #1: Convert loops to repeat..until form.
; for i := 1 to 249 -
mov i, 1
iloop:
; for j := 1 to 254 -
mov j, 1
jloop:
; Optimization. Unroll the innermost two loops:
mov bh, byte ptr i ;i is always less than 256.
mov bl, byte ptr j ;Computes i*256+j!
push ds
mov ax, InSeg ;Gain access to InSeg.
mov ds, ax
mov cx, 0 ;Compute sum here.
mov ah, ch
mov cl, ds:DataIn[bx-257] ;DataIn[i-1][j-1]
mov al, ds:DataIn[bx-256] ;DataIn[i-1][j]
add cx, ax
mov al, ds:DataIn[bx-255] ;DataIn[i-1][j+1]
add cx, ax
mov al, ds:DataIn[bx-1] ;DataIn[i][j-1]
add cx, ax
mov al, ds:DataIn[bx+1] ;DataIn[i][j+1]
add cx, ax
mov al, ds:DataIn[bx+255] ;DataIn[i+1][j-1]
add cx, ax
mov al, ds:DataIn[bx+256] ;DataIn[i+1][j]
add cx, ax
mov al, ds:DataIn[bx+257] ;DataIn[i+1][j+1]
add cx, ax
mov al, ds:DataIn[bx] ;DataIn[i][j]
shl ax, 3 ;DataIn[i][j]*8
add cx, ax
shr cx, 4 ;Divide by 16
mov ax, OutSeg
mov ds, ax
mov ds:DataOut[bx], cl
pop ds
inc j
cmp j, 254
jbe jloop
inc i
cmp i, 249
jbe iloop
inc h
mov ax, h
cmp ax, Iterations
jnbe Done
jmp 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.
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -