Консультация № 191245
25.07.2017, 12:45
0.00 руб.
25.07.2017, 13:01
0 37 1
Здравствуйте! У меня возникли сложности с таким вопросом:
Решил написать программку по смене видеостраниц,
(на 0 страницу выведу один символ и обозначу сообщение о номере страницы, на 1 страницу другой и обозначу подобным сообщением.
1. Как сделать паузу в программе? (чтоб увидеть смену страниц)
2. Почему после окончания программы у меня нет ничего на экране?

[code lang=asm h=200]CSEG segment
assume cs:CSEG,ss:CSEG,es:CSEG,ds:CSEG
org 100h
start:
;устанавливаем видеорежим 80*25
mov ax,3
int 10h
mov dx, offset Mes_1
mov ah,9
int 21h
mov al,1
call Simvol

;----------------------------------------
mov ah,0fh
int 10h

cmp bh, 0
jz Smena

Smena:
mov ah,05h
mov al,2
int 10h
mov dx, offset Mes_2
mov ah,9
int 21h

mov al,2
call Simvol
jmp Vihod



;---------vivod simvolov--------------
Simvol proc
mov bl,al
mov ax,0b800h
mov es,ax
mov di,0
mov ah,31
mov al,bl
mov cx,240
cicl:
mov es:[di],ax
inc di
inc di
loop cicl
ret
Simvol endp
;---------------------------------------

Vihod:
int 20h

Mes_1 db 'windows number zero!$'
Mes_2 db 'windows number one!$'
CSEG ends
end start[/code]

Обсуждение

давно
Старший Модератор
31795
6196
25.07.2017, 13:49
общий
Адресаты:
что либо наковыряли?
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
401251
75
25.07.2017, 14:21
общий
25.07.2017, 14:22
Цитата: Зенченко Константин Николаевич
что либо наковыряли?


Наковырял! Но не то, что нужно)))
Смена индексного регистра приводит к смене расположения курсора.
А я бы хотел чтоб моя программа на одну страницу выводила сообщение и символы, потом через некоторую паузу выводило другую страницу с другим сообщением и символами![code lang=asm h=150]CSEG segment
assume cs:CSEG,ss:CSEG,es:CSEG,ds:CSEG
org 100h
start:
;устанавливаем видеорежим 80*25
mov ax,3
int 10h
mov dx, offset Mes_1
mov al,1
call Simvol

;----------------------------------------
mov ah,0fh
int 10h

cmp bh, 0
jz Smena


Smena:
xor ax,ax
int 16h
mov si,40
mov ah,05h
mov al,2
int 10h
mov dx, offset Mes_2
mov al,2
call Simvol
jmp Vihod



;---------vivod simvolov--------------
Simvol proc
mov bl,al
mov ah,9
int 21h
mov ax,0b800h
mov es,ax
mov di,0
mov ah,31
mov al,bl
mov cx,240
cicl:
mov es:[di],ax
inc di
inc di
loop cicl
ret
Simvol endp
;---------------------------------------

Vihod:
int 20h

Mes_1 db 'windows number zero!$'
Mes_2 db 'windows number one!$'
CSEG ends
end start[/code]

Сейчас судя по результатам (приложение), программа выводит символы на нулевую страницу (далее страницы не меняются).
давно
Посетитель
401251
75
25.07.2017, 14:22
общий
А вот приложения))))
Прикрепленные файлы:
fa81bf8b2d989dec24fe436e521308c3.png
давно
Посетитель
401251
75
25.07.2017, 14:30
общий
Так с выводом строки я вроде разобрался. Ее оказывается нельзя вывести в видеобуфер функцией 9H прерывания 21h. Для вывода строк нужна функция 13 прерывания 10.
Вообще все что касается видеобуфера это прерывание 10.
давно
Старший Модератор
31795
6196
25.07.2017, 14:46
общий
Адресаты:
Цитата: Caesar
Смена индексного регистра приводит к смене расположения курсора.

Расположение курсора меняется по другому. И прямая запись в видео буфер на курсор не влияет.
Если внимательно посмотрите на свою картинку, курсор виден под словом cmd(под выделенной буквой) и загнала его туда функция вывода строки.
Вот код
[code lang=asm h=200]model tiny
;CSEG segment
;assume cs:CSEG,ss:CSEG,es:CSEG,ds:CSEG
.code
org 100h
start:
;устанавливаем видеорежим 80*25
mov ax,3
int 10h
mov dx,offset Mes_1
mov ah,9
int 21h
mov ax,2401h
mov si,0
call Simvol
;----------------------------------------
;mov ah,0fh
;int 10h
;cmp bh,0
;jz Smena
;Smena:
xor ax,ax
int 16h
mov ah,05h
mov al,1
int 10h
mov dx,offset Mes_2
mov ah,9
int 21h
mov ax,4202h
mov si,4096
;call Simvol
;jmp Vihod
;---------vivod simvolov--------------
Simvol proc
mov bx,ax
mov ax,0b800h
mov es,ax
mov di,40
add di,si
mov ax,bx
mov cx,240
cicl:
;moves:[di],ax
;incdi
;incdi
;loopcicl
rep stosw
ret
Simvol endp
;---------------------------------------
;Vihod:
;int 20h
Mes_1 db 'windows number zero!$'
Mes_2 db 'windows number one!$'
;CSEG ends
end start[/code]
результат работы виден на картинке.
Выводы, сможете озвучить?
Прикрепленные файлы:
070953ca45ee24f7c48abeea6ceee186.jpg
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
25.07.2017, 14:53
общий
Адресаты:
Забыл добавить, убрал все лишнее.
И ещё переходите на упрощенную систему описания сегментов.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
7438
7205
25.07.2017, 15:10
общий
Адресаты:
Предлагаю свой вариант:
Комментарии не писал, разбирайтесь самостоятельно [code lang=asm h=200]CSEG segment
assume cs:CSEG,ss:CSEG,es:CSEG,ds:CSEG
org 100h
start:
;устанавливаем видеорежим 80*25
mov ax,3
int 10h

xor bp, bp

main_loop:
mov si,offset Mes_1
mov bl,1
test bp, bp
jz set_Simbol
mov si,offset Mes_2
mov bl,2

set_Simbol:
call Simvol

xor ax,ax
int 16h

cmp al,1bh
je exit

xor bp, 1000h
mov ax, 0500h
test bp, bp
je set_page
inc al
set_page:
int 10h
jmp main_loop

exit:
int 20h

;---------vivod simvolov--------------
Simvol proc
mov ax, 0b800h
mov es, ax
mov di, bp
mov ah, 31
push di
str_loop:
lods byte ptr [si]
test al, al
je Simbol_next
stosw
jmp str_loop

Simbol_next:
pop di
add di, 80*2

mov al, bl
mov cx, 240
cicl:
stosw
loop cicl
ret
Simvol endp
;---------------------------------------

Mes_1 db 'windows number zero!',0
Mes_2 db 'windows number one!',0
CSEG ends
end start[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401251
75
25.07.2017, 15:27
общий
Цитата: Зенченко Константин Николаевич
Если внимательно посмотрите на свою картинку, курсор виден под словом cmd(под выделенной буквой) и загнала его туда функция вывода строки.
я именно поэтому и сделал вывод: "для смены позиции курсора"))
Упрощенная схема описания сегментов это
[code lang=asm]model tiny
.code [/code]?

Мне не все команды понятны:
1. rep stosw
2. И непонятны записи чисел (почему именно они)
mov ax, 2401h
//----------
mov ax,4202h
mov si,4096
сейчас загуглю! И озвучу выводы.

Пока вывод только один "Недостаточно знаний и мозг еще не переключился на мышление как у программиста. Вперед и с песней"





давно
Посетитель
401251
75
25.07.2017, 15:37
общий
25.07.2017, 15:43
mov ax, 2401h c эти понятно (цвет и номер символа)
mov ax,4202h - аналогичная ситуация
rep - повтор stosw - записать слово из регистра ax в ячейку памяти, адресуемую парой es:di
давно
Посетитель
401251
75
25.07.2017, 15:41
общий
mov di,40- для того, чтобы было видно сообщение.
mov si,4096 - это смещение (зачем так много) ?
давно
Посетитель
7438
7205
25.07.2017, 15:44
общий
Адресаты:
409610 = 100016 - размер одной страницы в байтах.
И, соответственно, смещение страницы 1 в сегменте 0b800h
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401251
75
25.07.2017, 15:54
общий
URL >>
постраничное деление адресного пространства видеопамяти в текстовом режиме имеет следующий вид:
– B800h:0000h – страница 0, смещение в диапазоне 0000h – 0FFFh
– B900h:0000h – страница 1, смещение в диапазоне 0000h – 0FFFh

Я думал смещение одной страницы 0FFFh?
давно
Посетитель
7438
7205
25.07.2017, 15:57
общий
Адресаты:
B900h:0000h это то же самое, что b800h:1000h
В курсе, как формируется адрес из сегмента и смещения?
Все правильно, 0-0fffh и есть 1000h адресов, принадлежащих одной странице.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401251
75
25.07.2017, 16:01
общий
Цитата: Лысков Игорь Витальевич
В курсе, как формируется адрес из сегмента и смещения?

Нет
0fffh - 4095
1000h - 4096
куда идет один адрес?
давно
Посетитель
7438
7205
25.07.2017, 16:02
общий
Адресаты:
Строго говоря, используются не 4096 байт, а только 4000 = 25 (строк) * 80 (символов в строке) * 2 (символ+атрибут)
Но для удобства под страницу с 25 строками отводится 4096 байт
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401251
75
25.07.2017, 16:05
общий
т.е. получается адресное пространство - это одно целое, и следующая страница начинается с 26 строки, последующая с 51. Таким образом мы можем прокручивать их туда-сюда
давно
Старший Модератор
31795
6196
25.07.2017, 16:05
общий
Адресаты:
Цитата: Caesar
это смещение (зачем так много)

80*25*2(количество символов в строке*количество строк*количество байт на символ) = 4000, а так как основная система двоичная, то ближайшая степень двойки большая 4000 - 4096. Большая, т.к. видео страница не может быть меньше. Эти 96 байт никем не используются, чудесное место для вирусов.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
401251
75
25.07.2017, 16:07
общий
Цитата: Зенченко Константин Николаевич
чудесное место для вирусов.
давно
Посетитель
7438
7205
25.07.2017, 16:09
общий
25.07.2017, 16:09
Адресаты:
куда идет один адрес?
счет начинается с 0
как формируется адрес из сегмента и смещения
Пусть имеем seg:off
Тогда 20-битный адрес получится, как сумма сегмента seg, умноженного на 16=10h (или сдвинутого налево на 4 бита или на одну hex-цифру) и смещения off.
Например:
0b800:1000h = 0b800*10h + 1000h = 0b8000h + 1000h = 0b9000h
0b900:0000h = 0b900*10h + 0000h = 0b9000h + 0000h = 0b9000h
Видим, что адреса равны
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401251
75
25.07.2017, 16:12
общий
Цитата: Зенченко Константин Николаевич
Выводы, сможете озвучить?

Программа работает
Я программу откоментировал в качестве вывода)
[code lang=asm h=200]start:
;устанавливаем видеорежим 80*25
mov ax,3
int 10h
;выводим сообщение
mov dx,offset Mes_1
mov ah,9
int 21h

mov ax,2401h ; установка цвета и номера 1-го символа для вывода
mov si,0 ; смещение
call Simvol

xor ax,ax ;=10h
int 16h ; ожидаем нажатие клавиши
mov ah,05h
mov al,1 ; №страницы
int 10h ; меняем страницу
;выводим сообщение
mov dx,offset Mes_2
mov ah,9
int 21h

mov ax,4202h ; установка цвета и номера 2-го для вывода
mov si,4096 ; смещение на следующую страницу

;---------vivod simvolov--------------
Simvol proc
mov bx,ax
mov ax,0b800h
mov es,ax
mov di,40
add di,si
mov ax,bx
mov cx,240
cicl:
rep stosw ;записываем слово из регистра ax в ячейку по адресу es:di
ret
Simvol endp [/code]
давно
Посетитель
7438
7205
25.07.2017, 16:13
общий
Адресаты:
следующая страница начинается с 26 строки, последующая с 51
Не совсем так. Размер страницы не кратен длине строки
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Старший Модератор
31795
6196
25.07.2017, 16:15
общий
Адресаты:
Цитата: Caesar
rep - повтор СХ - раз следующей команды stosw - записать слово из регистра ax в ячейку памяти, адресуемую парой es:di, и увеличить/уменьшить индексный регистр на размер записываемого значения(байт - 1, слово - 2 и т.д.)

синим это мои комменты.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
7438
7205
25.07.2017, 16:17
общий
Адресаты:
Посмотрите еще и мой вариант. Думаю, теперь все будет ясно с полуслова
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401251
75
25.07.2017, 16:19
общий
Цитата: Зенченко Константин Николаевич
rep - повтор СХ - раз следующей команды stosw - записать слово из регистра ax в ячейку памяти, адресуемую парой es:di, и увеличить/уменьшить индексный регистр на размер записываемого значения(байт - 1, слово - 2 и т.д.)

Так точно, про сх знал. А то что размер сам увеличивается на размер записываемого значения даже не подумал.
давно
Посетитель
401251
75
25.07.2017, 16:23
общий
Вывод: Моя ошибка в том, что я не знал(не понимал) про смещения!!
Вы помогли мне разобраться!
спасибо!
Таким макаром, еще 1,5 недели и я(мы) закончим Калашникова)))
давно
Старший Модератор
31795
6196
25.07.2017, 16:35
общий
Адресаты:
Цитата: Caesar
закончим Калашникова


Кончать его не нужно, он нам ещё живой нужен.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
7438
7205
25.07.2017, 16:41
общий
25.07.2017, 16:44
Адресаты:
адресуемую парой es:di, и увеличить/уменьшить индексный регистр
Есть еще один момент, на который хочу обратить внимание.
Команда rep stosw и аналогичные может делать как автоинкремент адреса, так автодекремент.
Как будет работать, зависит от специального флага D в регистре флагов. Обычно он равен 0 и тогда будет автоинкремент.
А вот если он будет равен 1, то получим автодекремент адреса.
Не забывайте об этом
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Старший Модератор
31795
6196
25.07.2017, 16:54
общий
это ответ
Здравствуйте, Caesar!

Цитата: Caesar
1. Как сделать паузу в программе? (чтоб увидеть смену страниц)
2. Почему после окончания программы у меня нет ничего на экране?

1)Добавляете в код функцию ввода с клавиатуры.
2)Потому, что Вы не туда выводите.
Исправленный вариант кода:
[code lang=asm h=200]model tiny
;CSEG segment
;assume cs:CSEG,ss:CSEG,es:CSEG,ds:CSEG
.code
org 100h
start:
;устанавливаем видеорежим 80*25
mov ax,3
int 10h
mov dx,offset Mes_1
mov ah,9
int 21h
mov ax,2401h
mov si,0
call Simvol
;----------------------------------------
;mov ah,0fh
;int 10h
;cmp bh,0
;jz Smena
;Smena:
xor ax,ax
int 16h
mov ah,05h
mov al,1
int 10h
mov dx,offset Mes_2
mov ah,9
int 21h
mov ax,4202h
mov si,4096
;call Simvol
;jmp Vihod
;---------vivod simvolov--------------
Simvol proc
mov bx,ax
mov ax,0b800h
mov es,ax
mov di,40
add di,si
mov ax,bx
mov cx,240
cicl:
;moves:[di],ax
;incdi
;incdi
;loopcicl
rep stosw
ret
Simvol endp
;---------------------------------------
;Vihod:
;int 20h
Mes_1 db 'windows number zero!$'
Mes_2 db 'windows number one!$'
;CSEG ends
end start[/code]
Удачи!
5
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
401251
75
26.07.2017, 07:58
общий
Адресаты:
Разобрал Вашу программу:
[code lang=asm h=250]CSEG segment
assume cs:CSEG,ss:CSEG,es:CSEG,ds:CSEG
org 100h
start:
mov ax,3 ;устанавливаем видеорежим 80*25
int 10h

xor bp, bp ; обнуление bp

main_loop:
mov si,offset Mes_1 ;записываем адрес сообщение в указатель
mov bl,1 ;номер символа
test bp, bp ; сравнение (операция И) переход если == 0
jz set_Simbol ;если флаг установлен в 1 переходим
mov si,offset Mes_2 ;записываем адрес сообщение в указатель
mov bl,2 ;номер символа

set_Simbol:
call Simvol

xor ax,ax ;(00h=10h)
int 16h ;ждем нажатия клавиши

cmp al,1bh ; сравнение на ESC
je exit ; да - выход

xor bp, 1000h ; в bp после xor будет 1000h - следующая страница/при следующем нажатии клавиши обнулиться
mov ax, 0500h;функция
test bp, bp ; сравнение на ноль
je set_page ;если ноль то таже страница
inc al ; если нет следующая страница (№ 1)
set_page:
int 10h ;сделать активной страницу 1
jmp main_loop

exit:
int 20h
;---------vivod строки и simvolov--------------
Simvol proc
mov ax, 0b800h ;адрес сегмента видеобуфера
mov es, ax ;напрямую не можем, поэтому посредник
mov di, bp ;смещение 0
mov ah, 31 ; цвет символа
push di ;сохраняем смещение
str_loop:
lods byte ptr [si] ;загрузка байта в al, находящегося по адресу [si]
test al, al ; сравнение (операция И) переход если ==0
je Simbol_next
stosw ;записываем слово из регистра ax в ячейку по адресу es:di
jmp str_loop

Simbol_next:
pop di ;извлекаем смещение
add di, 80*2 ;добавляем строку(переход на новую)

mov al, bl ;в аl номер символа
mov cx, 240 ;количество повторений
cicl:
stosw ;записываем слово из регистра ax в ячейку по адресу es:di и увеличиваем на
loop cicl
ret
Simvol endp
;---------------------------------------

Mes_1 db 'windows number zero!',0
Mes_2 db 'windows number one!',0
CSEG ends
end start[/code]

Спасибо! хорошая практика для меня!

давно
Посетитель
7438
7205
26.07.2017, 11:37
общий
26.07.2017, 11:38
Адресаты:
Чуток подправил комментарии:[code lang=asm h=200]CSEG segment
assume cs:CSEG,ss:CSEG,es:CSEG,ds:CSEG
org 100h
start:
mov ax,3 ;устанавливаем видеорежим 80*25
int 10h

xor bp, bp ;смещение для страницы в видеобуфере, сначала - нулевая

main_loop:
;определяем, что выводим и в какую страницу
;сначала считаем, что в нулевую
mov si,offset Mes_1 ;записываем адрес сообщение в указатель
mov bl,1 ;номер символа
test bp, bp ;проверяем, какая текущая страница
jz set_Simbol ;если 0, то страница 0
;иначе, готовим данные для станицы 1
mov si,offset Mes_2 ;записываем адрес сообщение в указатель
mov bl,2 ;номер символа

set_Simbol: ;вывод строки и символов в буфер текущей страницы
call Simvol

xor ax,ax ;(00h=10h)
int 16h ;ждем нажатия клавиши

cmp al,1bh ; сравнение на ESC
je exit ; да - выход

xor bp, 1000h ; меняем смещение страницы для следующего вывода
mov ax, 0500h;функция задает иекущую страницу для вывода, сначала считаем, что 0 страница (al=0)
test bp, bp ; нулевая страница?
je set_page ; да, устанавливаем текущей нулевую страницу
inc al ; если нет, устанавливаем текущей первую страницу
set_page:
int 10h ;сделать активной указанную страницу
jmp main_loop ;на вывод в активную странищу

exit:
int 20h
;---------vivod строки и simvolov--------------
Simvol proc
mov ax, 0b800h ;адрес сегмента видеобуфера
mov es, ax ;напрямую не можем, поэтому посредник
mov di, bp ;смещение текущей видеостраницы
mov ah, 31 ; цвет символа
push di ;сохраняем смещение
str_loop: ;выведем строку в первой строке экрана
lods byte ptr [si] ;загрузка байта в al, находящегося по адресу [si]
test al, al ; строка заканчивается нулем
je Simbol_next
stosw ;записываем слово из регистра ax в ячейку по адресу es:di
jmp str_loop

Simbol_next:
pop di ;извлекаем смещение
add di, 80*2 ;добавляем строку(переход на новую)

mov al, bl ;в аl номер символа
mov cx, 240 ;количество повторений
cicl:
stosw ;записываем слово из регистра ax в ячейку по адресу es:di и увеличиваем на слово
loop cicl
ret
Simvol endp
;---------------------------------------

Mes_1 db 'windows number zero!',0
Mes_2 db 'windows number one!',0
CSEG ends
end start
CSEG ends
end start[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа