Страница 1 из 1
Переопределение символов шрифта
Добавлено: 28 май 2004, 20:46
Игрек
Ребята, помогите пожалуста с Ассемблером. Нужно переопределить таблицу символов с помощью int 10h.
У меня есть хелп, но там непонятно написано. Не понятен синтаксис функции 11h, и прерывания int 1fh. Я знаю, что нужно для каждого символа определять массив 8 байт. Но как именно переопределить например вместо буквы A -букву Z
Добавлено: 29 май 2004, 00:31
Andy
Название темы я поменял.
Игрек, давайте осмысленные названия темам.
Не понятен синтаксис функции 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
Добавлено: 01 июн 2004, 12:34
Romeo
Вместо
можно было, особо не мудруствуя, написать

Добавлено: 01 июн 2004, 17:51
Игрек
Код:
mov ah, 4Ch
int 21h
можно было, особо не мудруствуя, написать
Код:
ret
А в чём мудрствование? Ведь Ret пишут в конце процедуры! А тут процедурой и не пахнет... Я учусь в Кубанском гос. университете на фак. Прикладной математики, и в первый раз слышу, что оказывается вместо
mov ah, 4C00h
int 21h
можно писать
ret
??! По-моему Romeo, ты не в тему влез..

)
Добавлено: 01 июн 2004, 17:57
Andy
Romeo прав. COM программу, в отличие от EXE можно завершить коммандой ret (если в стеке не осталось ничего лишнего) или еще int 20h. Только это в данном вопросе не важно.
Добавлено: 01 июн 2004, 19:31
Romeo
Игрек, я понимаю, что эти две строчки - далеко не самое главное в данное программе, но ты бы хоть как минимум попробовал перед тем, как столь резко спорить с более опытным человеком

(который уже окончил университет по специальности Computer Since, а не Прикладная, и в данный момент является программистом филиала уважаемой американской компании)
Добавлено: 01 июн 2004, 23:03
Игрек
Извини Romeo. Я был не прав. Но все равно ставить mov ax,4c00h, int 21h намного надежнее. Хотя в данном случае экономятся 4 байта.
Нужно следить за тем, чтобы не было дисбаланса стека. Я в основном пишу в EXE формате, поэтому мне удобнее так...

Добавлено: 06 июн 2004, 19:02
Игрек
Я сейчас приведу программный код. Скажите, где тут ошибка...
.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'
Пробовал запускать и в Досе, и в Виндах-везде один результат!

Добавлено: 06 июн 2004, 20:51
Andy
Скажите, где тут ошибка...
Игрек, ошибок много
.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) делать не надо. Повторяю, программа занимает один сегмент, так что все сегментные регистры после запуска равны друг другу и этому сегменту.