комментарии к программе
Добавлено: 28 май 2010, 12:15
Помогите пожалуйста прокомментировать первую часть программы:
.model small
.data
;закодированное изображение
content db 'Фрегат'
content_sz equ $-content ;размер текста
fontname db '16x10.f',0 ;растровый шрифт, где на каждую букву хранится матрица 16x10, которая и содержит попиксельное представление символа
;
open_err db 10,13,'Open error$'
seek_err db 10,13,'Seek error$'
read_err db 10,13,'Read error$'
tdx dw ? ;временно хранится y
letter dw 10 dup (?)
txt_last dw ?
txt db 32*10*8 dup (?)
font_H equ 16
.stack 256
.code
start: mov ax, @data ;инициализируем сегментные регистры
mov ds, ax
mov es, ax
mov ax, 3d00h
mov dx, offset fontname
int 21h
jnc read_init
mov dx, offset open_err
jmp err_msg
read_init:
mov bx, ax
mov si, offset content
mov di, offset txt
mov cx, content_sz
read_loop:
push cx
xor ax, ax
lodsb
mov cx, 20
mul cx
mov dx, ax
xor cx, cx
mov ax, 4200h
int 21h
jnc read
mov dx, offset seek_err
jmp err_msg
read:
mov ah, 3fh
mov cx, 20
mov dx, offset letter
int 21h
jnc decode
mov dx, offset read_err
jmp err_msg
decode:
push si
mov si, offset letter
mov cx, 10
l1:
lodsw
mov dx, 8000h
push cx
mov cx, 16
l2:
test ax, dx
jnz i1
mov byte ptr [di], 0
jmp i2
i1:
mov byte ptr [di], 3
i2:
inc di
shr dx, 1
loop l2
pop cx
loop l1
pop si
pop cx
loop read_loop
mov txt_last, di
mov ah, 3eh
int 21h
mov ax, 0a000h
mov es, ax
mov ax, 0013h
int 10h ;устанавливаем видеорежим 320*240*256 цветов
mov cx, 38400 ;очищаем экран
xor ax, ax
xor di, di
rep stosw
mov bx, 1 ;коэффициент масштабирования
m2: call scaled_text;выволим картинку с заданным масштабом
inc bx ;увеличиваем масштаб
in al, 60h ;читаем из порта клавиатуры
cmp al, 1 ;если нажата ESC, то выход
jz ex
call waitp ;задержка
cmp bx, 7 ;достигли максимального масштаба
jnz m2 ;если нет, продолжаем
dec bx ;корректируем масштаб
m3: call scaled_text;выволим картинку с заданным масштабом
dec bx ;увеличиваем масштаб
call waitp ;ожидание
cmp bx, 0 ;достигли минимального масштаба?
jnz m3 ;если нет, продолжаем
inc bx ;корректируем масштаб
jmp m2 ;начинаем сначала
err_msg:
mov ah, 09
int 21h
ex: mov ax, 4c00h ;выход из программы
int 21h
waitp: push cx ;подпрограмма задержки выполнения программы
push dx
mov dx, 6000 ;Поскольку у меня не работает функция 86h int 16h(задержка)
llp1: xor cx, cx
llp: loop llp ;внутренний цикл ожидания
in al, 60h ;читаем из порта клавиатуры
cmp al, 1 ;если нажата ESC, то выход
jz ex
;то будем приостанавливать программу при помощи циклов ожидания
dec dx
jnz llp1 ;внешниq цикл ожидания
pop dx
pop cx
ret
scaled_text: ;вывод в центре экрана отмасштабированой картинки. bx - масштаб
mov si, offset txt;начало картинки
mov ax, txt_last
sub ax, offset txt
xor dx, dx
mov cx, font_H
div cx ;длина строки картинки
mul bx ;умножаем масштаб на длину строки
mov cx, 320
sub cx, ax
jge work
ret
work:
shr cx, 1 ;получаем коорд левого угла отмасштабир картинки, выводивой в центр экрана
mov ax, font_H
mul bx
mov dx, 200
sub dx, ax
shr dx, 1 ;получаем коорд верхнего угла отмасштабир картинки, выводивой в центр экрана
mov tdx, dx ;сохраняем dх
push cx
mov cx, 38400 ;очищаем экран
xor ax, ax
xor di, di
rep stosw
pop cx
xor di, di ;счетчис столбца картинки
lp: cmp si, txt_last; проверяем достигли ли конца картинки
jz skip ;если достигли, то заканчиваем вывод
lodsb ;берем байт(пиксель) из картинки
inc di ;увеличиваем счетчик столбцов
call scaled_pixel;выводим отмасштабированый пиксель
add dx, bx ;переходим к следующей горизонтальной координате
cmp di, font_H ;если закончиласть строка картинки
jnz m1
xor di, di ;то обнулить счетчик
mov dx, tdx ;восстановить сх
add cx, bx ;увеличикаем координату y
m1: jmp lp ;продолжаем вывод
skip: ret ;выход из подпрограммы
;подпрограмма вывода отмасштабированного пикселя
scaled_pixel:
push di ;сохраняем регистры
push si
push dx
push cx
push bx
push ax
mov si,bx ;сохраняем масштаб
mov ax,320
mul dx ;y*320
add ax,cx ;y*320+х
mov di,ax ;получили адрес верхнего левого угола квадратика
pop ax ;восстанавливаем цвет пикселя
pxlp: mov cx,si ;количество пикселей погориз=масштабу
push di ;сохраняем адрес верхнего левого угола квадратика
rep stosb ;выводим строку пикселей из квадратика
pop di ;восстанавливаем адрес верхнего левого угола квадратика
add di,320 ;переходим на следующую строку
dec bx ;уменьшаем количество оставшихся строк
jnz pxlp ;продолжаем пока не выведем все
pop bx ;восстановить регистры
pop cx
pop dx
pop si
pop di
ret ;выход
end start
.model small
.data
;закодированное изображение
content db 'Фрегат'
content_sz equ $-content ;размер текста
fontname db '16x10.f',0 ;растровый шрифт, где на каждую букву хранится матрица 16x10, которая и содержит попиксельное представление символа
;
open_err db 10,13,'Open error$'
seek_err db 10,13,'Seek error$'
read_err db 10,13,'Read error$'
tdx dw ? ;временно хранится y
letter dw 10 dup (?)
txt_last dw ?
txt db 32*10*8 dup (?)
font_H equ 16
.stack 256
.code
start: mov ax, @data ;инициализируем сегментные регистры
mov ds, ax
mov es, ax
mov ax, 3d00h
mov dx, offset fontname
int 21h
jnc read_init
mov dx, offset open_err
jmp err_msg
read_init:
mov bx, ax
mov si, offset content
mov di, offset txt
mov cx, content_sz
read_loop:
push cx
xor ax, ax
lodsb
mov cx, 20
mul cx
mov dx, ax
xor cx, cx
mov ax, 4200h
int 21h
jnc read
mov dx, offset seek_err
jmp err_msg
read:
mov ah, 3fh
mov cx, 20
mov dx, offset letter
int 21h
jnc decode
mov dx, offset read_err
jmp err_msg
decode:
push si
mov si, offset letter
mov cx, 10
l1:
lodsw
mov dx, 8000h
push cx
mov cx, 16
l2:
test ax, dx
jnz i1
mov byte ptr [di], 0
jmp i2
i1:
mov byte ptr [di], 3
i2:
inc di
shr dx, 1
loop l2
pop cx
loop l1
pop si
pop cx
loop read_loop
mov txt_last, di
mov ah, 3eh
int 21h
mov ax, 0a000h
mov es, ax
mov ax, 0013h
int 10h ;устанавливаем видеорежим 320*240*256 цветов
mov cx, 38400 ;очищаем экран
xor ax, ax
xor di, di
rep stosw
mov bx, 1 ;коэффициент масштабирования
m2: call scaled_text;выволим картинку с заданным масштабом
inc bx ;увеличиваем масштаб
in al, 60h ;читаем из порта клавиатуры
cmp al, 1 ;если нажата ESC, то выход
jz ex
call waitp ;задержка
cmp bx, 7 ;достигли максимального масштаба
jnz m2 ;если нет, продолжаем
dec bx ;корректируем масштаб
m3: call scaled_text;выволим картинку с заданным масштабом
dec bx ;увеличиваем масштаб
call waitp ;ожидание
cmp bx, 0 ;достигли минимального масштаба?
jnz m3 ;если нет, продолжаем
inc bx ;корректируем масштаб
jmp m2 ;начинаем сначала
err_msg:
mov ah, 09
int 21h
ex: mov ax, 4c00h ;выход из программы
int 21h
waitp: push cx ;подпрограмма задержки выполнения программы
push dx
mov dx, 6000 ;Поскольку у меня не работает функция 86h int 16h(задержка)
llp1: xor cx, cx
llp: loop llp ;внутренний цикл ожидания
in al, 60h ;читаем из порта клавиатуры
cmp al, 1 ;если нажата ESC, то выход
jz ex
;то будем приостанавливать программу при помощи циклов ожидания
dec dx
jnz llp1 ;внешниq цикл ожидания
pop dx
pop cx
ret
scaled_text: ;вывод в центре экрана отмасштабированой картинки. bx - масштаб
mov si, offset txt;начало картинки
mov ax, txt_last
sub ax, offset txt
xor dx, dx
mov cx, font_H
div cx ;длина строки картинки
mul bx ;умножаем масштаб на длину строки
mov cx, 320
sub cx, ax
jge work
ret
work:
shr cx, 1 ;получаем коорд левого угла отмасштабир картинки, выводивой в центр экрана
mov ax, font_H
mul bx
mov dx, 200
sub dx, ax
shr dx, 1 ;получаем коорд верхнего угла отмасштабир картинки, выводивой в центр экрана
mov tdx, dx ;сохраняем dх
push cx
mov cx, 38400 ;очищаем экран
xor ax, ax
xor di, di
rep stosw
pop cx
xor di, di ;счетчис столбца картинки
lp: cmp si, txt_last; проверяем достигли ли конца картинки
jz skip ;если достигли, то заканчиваем вывод
lodsb ;берем байт(пиксель) из картинки
inc di ;увеличиваем счетчик столбцов
call scaled_pixel;выводим отмасштабированый пиксель
add dx, bx ;переходим к следующей горизонтальной координате
cmp di, font_H ;если закончиласть строка картинки
jnz m1
xor di, di ;то обнулить счетчик
mov dx, tdx ;восстановить сх
add cx, bx ;увеличикаем координату y
m1: jmp lp ;продолжаем вывод
skip: ret ;выход из подпрограммы
;подпрограмма вывода отмасштабированного пикселя
scaled_pixel:
push di ;сохраняем регистры
push si
push dx
push cx
push bx
push ax
mov si,bx ;сохраняем масштаб
mov ax,320
mul dx ;y*320
add ax,cx ;y*320+х
mov di,ax ;получили адрес верхнего левого угола квадратика
pop ax ;восстанавливаем цвет пикселя
pxlp: mov cx,si ;количество пикселей погориз=масштабу
push di ;сохраняем адрес верхнего левого угола квадратика
rep stosb ;выводим строку пикселей из квадратика
pop di ;восстанавливаем адрес верхнего левого угола квадратика
add di,320 ;переходим на следующую строку
dec bx ;уменьшаем количество оставшихся строк
jnz pxlp ;продолжаем пока не выведем все
pop bx ;восстановить регистры
pop cx
pop dx
pop si
pop di
ret ;выход
end start