Переопределение символов шрифта

Низкоуровневое программирование портов, микроконтроллеров и т.д.

Модератор: Andy

Ответить
Игрек
Сообщения: 12
Зарегистрирован: 28 май 2004, 20:35

Ребята, помогите пожалуста с Ассемблером. Нужно переопределить таблицу символов с помощью int 10h.
У меня есть хелп, но там непонятно написано. Не понятен синтаксис функции 11h, и прерывания int 1fh. Я знаю, что нужно для каждого символа определять массив 8 байт. Но как именно переопределить например вместо буквы A -букву Z
Andy
Сообщения: 238
Зарегистрирован: 17 фев 2004, 08:15
Откуда: Минск

Название темы я поменял. Игрек, давайте осмысленные названия темам.
Не понятен синтаксис функции 11h
Это функция по установке пользовательских символов при AL == 0. Таким образом:

ax - 1100h
bl - номер блока шрифта 0..4 (сам не четко понимаю что это такое, всегда ставил 0).
bh - размер в байтах (для обычного режима EGA он == 16, так как символ 8х16. Но можно и 8х8 и 8х14...)
cx - колличество замещаемых символов
dx - ASCII код первого подлежащего замене
es:bp - адрес массива байт представляющих символ (я так понимаю вы в курсе). Число байт на символ разумеется == bh

Вот и все.
и прерывания int 1fh
По-моему там указатель на таблицу для первых 128 символов и то для CGA. Хотя я этим делом лет 5 не занимался что0то забыл.

В нижеприведенной проге вместо символа A выведется вертикальная полоса. ПОД Windows в дос-окне или как угодно работать НЕ БУДЕТ. Только чистый дос! Проверок на поддержку режимов и ошибки не делается.

Код: Выделить всё

	.model tiny
	.code
	org 100h
start:
	mov	ax,3
	int	10h

	mov	ax,1100h
	mov	bx,1000h
	mov	cx,1
	mov	dx,'A'
	mov	bp,offset symb_A
	int	10h
	
	mov	ah,9
	mov	dx,offset string
	int	21h
	
	mov	ah,4ch
	int	21h

string	db "ABCDEFGHIJKLMNOPQRSTUVWXYZ",'$'
	
symb_A	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	db 00011000b
	
end	start
*provided AS IS
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Вместо

Код: Выделить всё

mov   ah, 4Ch
int    21h
можно было, особо не мудруствуя, написать :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Игрек
Сообщения: 12
Зарегистрирован: 28 май 2004, 20:35

Код:

mov ah, 4Ch
int 21h


можно было, особо не мудруствуя, написать
Код:

ret
А в чём мудрствование? Ведь Ret пишут в конце процедуры! А тут процедурой и не пахнет... Я учусь в Кубанском гос. университете на фак. Прикладной математики, и в первый раз слышу, что оказывается вместо
mov ah, 4C00h
int 21h
можно писать
ret
??! По-моему Romeo, ты не в тему влез.. :) )
Andy
Сообщения: 238
Зарегистрирован: 17 фев 2004, 08:15
Откуда: Минск

Romeo прав. COM программу, в отличие от EXE можно завершить коммандой ret (если в стеке не осталось ничего лишнего) или еще int 20h. Только это в данном вопросе не важно.
*provided AS IS
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Игрек, я понимаю, что эти две строчки - далеко не самое главное в данное программе, но ты бы хоть как минимум попробовал перед тем, как столь резко спорить с более опытным человеком :) (который уже окончил университет по специальности Computer Since, а не Прикладная, и в данный момент является программистом филиала уважаемой американской компании)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Игрек
Сообщения: 12
Зарегистрирован: 28 май 2004, 20:35

Извини Romeo. Я был не прав. Но все равно ставить mov ax,4c00h, int 21h намного надежнее. Хотя в данном случае экономятся 4 байта.
Нужно следить за тем, чтобы не было дисбаланса стека. Я в основном пишу в EXE формате, поэтому мне удобнее так... :)
Игрек
Сообщения: 12
Зарегистрирован: 28 май 2004, 20:35

Я сейчас приведу программный код. Скажите, где тут ошибка...


.model tiny
.stack
.code
org 100h
beg: push cs
pop ds
mov dx, offset mes
mov ah,09h
int 21h

; теперь переопределение символа
mov bl,0
mov bh,08h
mov ax,1100h
mov cx,1
mov dx,'a'
push cs
pop es
lea bp, red
int 10h

mov dx, offset mes
mov ah,09h
int 21h

mov ax,4c00h
int 21h

mes db 'abcdefghijklmnopqrstuvwxyz $'
red db '10000001'
db '10000011'
db '10000101'
db '10001001'
db '10010001'
db '10100001'
db '11000001'
db '10000001'

end beg

Но вместо буквы 'И' выводится на экран что-то типа

db '11000000'
db '11000110'
db '11000110'
db '11000000'
db '11000000'
db '11000000'
db '11000000'
db '11000110'
db '11000110'
db '11000000'
db '11000000'
db '11000000'
db '11000000'
db '11000110'
db '11000110'
db '11000000'
Пробовал запускать и в Досе, и в Виндах-везде один результат! :(
Andy
Сообщения: 238
Зарегистрирован: 17 фев 2004, 08:15
Откуда: Минск

Скажите, где тут ошибка...
Игрек, ошибок много :)
.stack
Если ты компилируешь программу как COM, что вобщем-то видно, то в этом месте компилятор должен выдать ошибку. Программа даже не должна скомпилироваться. COM программа занимает только один сегмент, а ты еще объявляешь один - сегмент стека. Эту строку надо убрать и линковать с ключем /t для tlink.exe.
red db '10000001'
db '10000011'
db '10000101'
db '10001001'
db '10010001'
db '10100001'
db '11000001'
db '10000001'
Хм... Я же пример приводил. Зачем тут кавычки?! В место одного байта в каждой строке ты объявляешь 8 байт. Кавычки убери и добавь в конце b, что бы показать компилятору что это в двоичной форме. Вот так:

Код: Выделить всё

red db 10000001b 
db 10000011b 
db 10000101b 
db 10001001b 
db 10010001b 
db 10100001b 
db 11000001b 
db 10000001b
Так как ты определяешь символы 8х8, то в обычном режиме (а он 8х16) получится ерунда. Вместо буквы 'И', верхних 8 пикселей буквы 'a' будут как буква 'И', а нижние 8 - то, что осталось от буквы 'a'.

И еще, к слову. В COM программе push cs/pop ds (es) делать не надо. Повторяю, программа занимает один сегмент, так что все сегментные регистры после запуска равны друг другу и этому сегменту.
*provided AS IS
Ответить