Заполнить квадрат NxN по спирали против часовой стрелки от внутренней части квадрата к внешней цифрами 0..9 и последовательно менять цвета.
;zapolnit kwadrat NxN po spirali protiv napravlenija chasowoj strelki
;ot wnutrennej chasti kwadrata k wneshnej
;ciframi ot 0-9 i posledowatelno menjat cveta
format mz
begin:
org 0x100
;директиву ORG.Начало бинарного файла. Функция этой директивы задавать начальный адрес программы, с которого она располагается при загрузке в память
;колиство факториалов
;квадрат заполняем числами
call vvod ;вызываем процедуру ввода числа n
;Описания цикла
;сначало идем влево затем вниз
;увеличием реальный размер квадрата и сверяем с максимаьным если равны
;то идем на выход и предварительно дорисовываем нижнюю линию
;если не равны то идем вправо а затем вверх и увеличиваем рельный размер кваддрата
;и соответственно сверяем с максимальным размером если равны то идем в право и на выход
;если то в начало цикла
;-реальный размер это наш шаг который рисует сторону
mov ax,03 ;полная очистка экрана
int 10h ; ochistka ekrana
xor dx,dx ;обнуляем dx
mov dl,15 ;затем указываем цент нашего квадрата
mov dh,9 ;dl=столбец dh=строка
call vuvod_simvol ;выводим первый символ
call nextsimvol ;затем вызываем процедуру чтоб увеличили цифру и цвет
mov bh,[n];-максимум, тоесть максимальная виличина нашего квадрата ;[указатель на ссылки к адресу памяти]
mov bl,1 ;-счетчик, реальный размер кварата
;и тут сразу сверили не равно ли максимум размеру нашего квадрата
cmp bh,bl ;сверяем размер квадрата с максимальным размером
je exitP ; если они равны то идем в конец проги
go:
xor cx,cx ;обнуляем cx
mov cl,bl ;затем вносим в младшую часть сх, bl(там реальный размер кварата)
;все это для того чтоб сделато нужное количество шагов в цикле
levo: ; начало цикла
dec dl ; уменьшаем dl - столбец в котором выведем сивол
call vuvod_simvol ;выводим сивол
call nextsimvol ;затем перходим на следующий символ
loop levo
;-------- все по аналогии
xor cx,cx ;обнуляем cx
mov cl,bl
niz:
inc dh ;увеличивает содержимое на 1
call vuvod_simvol
call nextsimvol
loop niz
;---------
inc bl ; увеличиваем реальный размер квадрата а затем сверяем с максимальным
cmp bl,bh ;cmp - тоже , что и sub но не меняет аргументы
jge endp ; переход на метку , регистр
;--------
xor cx,cx ;обнуляем cx
mov cl,bl
pravo:
inc dl ;???????????????????????????
call vuvod_simvol
call nextsimvol
loop pravo
;-----------
;--------
xor cx,cx
mov cl,bl
vverh:
dec dh
call vuvod_simvol
call nextsimvol
loop vverh
;-----------
inc bl
cmp bl,bh
jge endv ; перехож если больше или меньше
jmp go ; идем в начало цикла
endp:
dec bl ;отнимаем один так как мы его увеличели перед тем как попасть сюда
;--------и дорисовываем идя вправо , вернее низ квадрата
xor cx,cx ;обнуляем cx
mov cl,bl
pravoE:
inc dl
call vuvod_simvol
call nextsimvol
loop pravoE
;-----------
jmp exitP
endv:
dec bl ;уменьшает на 1
xor cx,cx
mov cl,bl
levoE: ; а тут орисовываем вверхнюю часть
dec dl
call vuvod_simvol
call nextsimvol
loop levoE
exitP:
;перед выходом зададим положение курсора
mov ah,2
mov bh,0
mov dh,24 ;строка
mov dl,7 ;столбец
int 10h
mov ah,0x4C ;эта функция завершает программу
mov al,0 ;код возврата 0
int 0x21 ;вызываем ядро операционной системы
;======================================================
;переменые наши
s db 0; обявили переменню temp которая равна 0
n db 4
cvet db 1
buf db "0000000000"
vvediteN db "Vvediet N(1<=n<=10):$"
error db "vvedeno nevernoe znachenie! (1<=n<=10)! Povtorite vvod!",10,13,'$'
;=====================================================
;====================================================
vuvod_simvol: ;метод вывоит символ на экран
;dh- строка
;dl- столбец
;заносим все регистры в стек чтоб не потерять их значение
;
push ax
push bx
push cx
push dx
mov ah,2
mov bh,0
;mov dh,23 ;строка
;mov dl,7 ;столбец
int 10h
;указываем цвет
mov ah,9h
mov BH,0 ;номер видео страницы
mov AL,' '; = записываемый символ
mov CX,1 ;= счетчик (сколько экземпляров символа записать)
mov BL,[cvet]; = видео атрибут (текст) или цвет (графика)
; (графические режимы: +80H означает XOR с символом на экране)
int 10h
mov al,[cvet]
inc al
mov [cvet],al
pop dx
push dx
;затем снова положение
mov ah,2
mov bh,0
;mov dh,23 ;строка
;mov dl,7 ;столбец
int 10h
;и выводим символ
mov ah,2 ;???????????????????????????
mov dl,[s] ;???????????????????????????
add dl,30h
int 21h
;ждем нажатия на энтер
@@:
mov ah,00;команда на ввод символа который будет помещен в AL
int 16h;
;заносим снова в переменую то этот регистр иземиться в ходе проги
cmp al,20h;сейчас пробел , а (0xD Enter)
jne @r; переходим на конец проги
;---------------------
;======================
pop dx ; получаем число из регистра .
pop cx
pop bx
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;===========================================
nextsimvol: ;увеличиваем символ на еденицу
push ax
mov al,[s]
inc al ;увеличивает содержимое на 1
cmp al,10
jne nextsimvolexit
mov al,0
nextsimvolexit:
mov [s],al
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;==========================================
strTodgt: ; строку в число, принимает строку si , вывод в ах
;метод который переводит с строки в числовой формат
mov dx,0
strTodgt_go: ;начало цикла
mov ax,0
mov cx,0
mov al,[si]
cmp al,'$' ;разделитель между числами
je strTodgt_exit
sub al,30h ;для получения самой цифры по ее коду мы должны вычесть 30h,; вычитаем из содержимому регистра AL 30H(H значит, что число в 16-тиричной системе счисления)
mov cx,ax
mov bx,10 ;???????????????????????????
mov ax,0 ;???????????????????????????
mov ax,dx
mul bx ;???????????????????????????; помогает проверять лежит ли числов диаппазоне от 0 до 10если что не позволяет ввести больше или меньше(ограничивает ввод)
add ax,cx ;???????????????????????????
mov dx,ax
inc si ;увеличивает содержимое на 1
jmp strTodgt_go
strTodgt_exit:
mov ax,dx
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;=================================
vvod:
;ввод самого числа происходит
jmp vvod_go
vvod_err:
mov ah,9h
mov dx,error
int 21h
vvod_go:
mov ah,9h
mov dx,vvediteN
int 21h
mov ah,3Fh ;тут происходит ввод строки ;???????????????????????????
mov bx,0
mov cx,5 ; максимум символов
mov dx,buf
int 21h
add dx,ax ; ???????????????????????????
mov ah,'$' ; ;??????????????????????????? вставляет в строку символ $ что бы понять что строка закончилась и перейти к другой
mov si,dx
sub si,2 ;??????????????????????????? ; sub si,2; это i:=i-2 счелкает по символам ; резервируем часть стека для данных
mov [si],ah ;записывает символ
mov si,buf ;???????????????????????????
call strTodgt
cmp ax,10
jg vvod_err
cmp ax,0
jle vvod_err
mov [n],al
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;=================================
|