📄 imgprcs3.asm
字号:
; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -