Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
0 / 0 / 2
Регистрация: 23.05.2018
Сообщений: 14
FASM

Замена символа в знакогенераторе

24.07.2020, 19:44. Показов 3074. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Написал программу, которая меняет символ ascii код 128 на мною созданный и выводит этот символ, но в итоге ничего не выводится
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
mov ax,cs
mov ds,ax
xor ax,ax
xor dx,dx
mov ah,0h
mov al,3h ;текст 80*25
int 10h
mov dx,3c4h
mov al,3
out dx,al ;записываю в порт 3c4h номер регистра выбора карты символов
mov dx,3c5h
in al,dx ;читаю из порта 3c5h значение регистра
or al,00000100b ;пара битов 3-2 дает номер блока символов, который берется, когда бит 3 байта атрибутов установлен в 1
out dx,al
mov bp,chdt ;bp указывает на смещение данных(символ 8*14 пикселей, то есть для создания символа нужно 14 байт)
mov cx,1 ;число символов
mov dx,128 ;начальное смещение
mov bl,1 ;блок символов
mov bh,14 ;14 байт требуется для создания символов
mov ah,11h ;генерирует символы
mov al,1h
int 10h
xor ax,ax
xor bx,bx
xor di,di
mov ax,0b800h
mov es,ax
mov ah,00001001b
mov al,128
mov [es:di],ax
mov ah,4ch
int 21h
chdt db 00011000b,00111100b,01111110b,11111111b
db 11111111b,11111111b,11111111b
db 11111111b,11111111b,11111111b,11111111b
db 01111110b,00111100b,00011000b
Так как все же создать специальный символ?

Добавлено через 28 минут
Теперь код не с того, ни с сего начал работать, что?????? Точно тот же код. Опять перестал.

Добавлено через 15 минут
Да, все, не работает. В чем может быть проблема?

Добавлено через 29 минут
Через функцию 11h, подфункцию 30h, прерывания 10h узнал сколько нужно байтов для символов, написано 16 байтов, пробовал изменить bh на 16, но все равно не работает

Добавлено через 1 час 24 минуты
Проблема решена, подфункция должна быть 0h. Нашел в гугле полное описание функции 11h прерывания 10h и ее подфункций

Добавлено через 1 минуту
Спрашивается, зачем вопрос создавал
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.07.2020, 19:44
Ответы с готовыми решениями:

Замена в знакогенераторе символа "A"
есть код code segment assume cs:code, ds:code, cs:code org 100h begin: jmp beg font: db 11111111b db 10000001b db...

Замена символа в строке на число соответствующему номеру по порядку вхождения этого символа в строку
В заданной строке заменить каждый символ «*» числом, соответствующим номеру по порядку вхождения этого символа в строку.

Замена символа на их сочетание - происходит множественная замена
примером есть у меня текст типа "globus" замена у меня происходит так: gg = gg.Replace("a", "1bf"); ...

5
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8659 / 4495 / 1669
Регистрация: 01.02.2015
Сообщений: 13,906
Записей в блоге: 12
24.07.2020, 19:45
Лучший ответ Сообщение было отмечено surfgamer как решение

Решение

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
use16                                   ;Генерировать 16-битный код
org 100h                                ;Программа начинается с адреса 100h
 
 
        mov     ax,     1110h           ;Load and Activate User-Defined Font
        mov     bh,     14              ;height of each character (bytes per character definition)
        mov     bl,     0               ;font block to load (EGA: 0-3; VGA: 0-7)
        mov     cx,     1               ;number of characters to redefine
        mov     dx,     128             ;ASCII code of the first character defined at ES:BP
        mov     bp,     chdt            ;address of font-definition information
        push    ds
        pop     es
        int     10h
 
        mov     al,     128
        int     29h
 
 
        mov     ah,     08h
        int     21h
 
        mov     ax,     4C00h           ;В регистр AH помещаем 4Ch, в AL – 00h.
        int     21h                     ;Завершение программы
;-------------------------------------------------------
chdt    db      00011000b
        db      00111100b
        db      01111110b
        db      11111111b
        db      11111111b
        db      11111111b
        db      11111111b
        db      11111111b
        db      11111111b
        db      11111111b
        db      11111111b
        db      01111110b
        db      00111100b
        db      00011000b
Смысл значения BL - font block - при равенстве 1 это второй шрифт, который выводится с атрибутом фона более 8.
Но для этого нужно ещё разрешить использование font block = 1 (второго шрифта) - INT 10H 1003H: Select Foreground Blink or Bold Background.

Если вы добавляете шрифт в блок 1, то он будет использоваться с атрибутами фона более 8, а при атрибутах фона менее 8 будет использоваться "старый" шрифт.
1
0 / 0 / 2
Регистрация: 23.05.2018
Сообщений: 14
24.07.2020, 19:48  [ТС]
Лучший ответ Сообщение было отмечено ФедосеевПавел как решение

Решение

Я уже разобрался, спасибо)
0
0 / 0 / 2
Регистрация: 23.05.2018
Сообщений: 14
25.07.2020, 05:50  [ТС]
А никто не знает по каким адресам находятся блоки шрифтов?(что б делать это без прерывания 10h)
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8659 / 4495 / 1669
Регистрация: 01.02.2015
Сообщений: 13,906
Записей в блоге: 12
25.07.2020, 12:26
Я сам никогда не интересовался программированием видеокарт, но видел фрагменты кодов, в которых на время шрифт отображался из памяти видеокарты на память процессора, а потом всё отключалось. Причём, человек набирал код в браузере, т.е. просто понимая происходящее.

Таким образом, работа производилась в таком порядке
1. отобразить шрифт на память процессора
2. обработка шрифта
3. закрытие отображения

Это рабочий код - проверял.
Кликните здесь для просмотра всего текста
Цитата Сообщение от AndNot
Для изменения знакогенератора необходимо открыть к нему доступ. Это делается через разрешение доступа ко 2-й плоскости, где и расположен знакогенератор:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
       cli
       ; turn off Sequence Controller
       mov     dx, 3c4h
       xor     al, al
       out     dx, al
       inc     dx
       inc     al
       out     dx, al
       ; сбрасываем регистр синхронизации
       dec     dx
       xor     al, al
       out     dx, al
       inc     dx
       mov     al, 3
       out     dx, al
       ; выбираем режим видеопамяти
       dec     dx
       inc     al
       out     dx, al
       inc     dx
       mov     al, 7            ; текстовый, более 64Kb, четный режим
       out     dx, al
       ; разрешаем запись в слой 2 (знакогенератор) и запрещаем запись в слои 0 и 1 (коды символов и их атрибуты)
       dec     dx
       mov     al, 2
       out     dx, al
       inc     dx
       add     al, 2
       out     dx, al
       ; выбираем схему чтения в регистре графического контроллера
       mov     dx, 3ceh
       mov     al, 4
       out     dx, al
       inc     dx
       mov     al, 2            ; номер считываемой битовой матрицы (на нужна 2-я, т.е. знакогениратор)
       out     dx, al
       ; настраиваем режим записи и считывания графического контроллера
       dec     dx
       mov     al, 5
       out     dx, al
       inc     dx
       xor     al, al           ; непосредственная запись/графический режим
       out     dx, al
       ; подправляем регистр смешанных данных
       dec     dx
       mov     al, 6
       out     dx, al
       inc     dx
       mov     al, 4            ; сегмент окна для доступа - 0A000h, 64Кб
       out     dx, al
       sti
После этого можешь изменять шрифт, находящийся во второй плоскости, по адресу 0A000h:0000h. В принципе адрес можно любой задать, но так удобнее.
После изменений, необходимо закрыть доступ к знакогенератору и разрешить к плоскостям 0 и 1, которые содержат коды символов и их атрибуты:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
       cli
       ; turn off Sequence Controller
       mov     dx, 3c4h
       xor     al, al
       out     dx, al
       inc     dx
       inc     al
       out     dx, al
       ; сбрасываем регистр синхронизации
       dec     dx
       xor     al, al
       out     dx, al
       inc     dx
       mov     al, 3
       out     dx, al
       ; ввосстанавливаем режим видеопамяти
       dec     dx
       inc     al
       out     dx, al
       inc     dx
       dec     al
       out     dx, al
       ; разрешаем запись в слои 0 и 1, и запрещаем в слой 2
       dec     dx
       dec     al
       out     dx, al
       inc     dx
       inc     al
       out     dx, al
       ; восстанавливаем схему чтения в регистре графического контроллера
       mov     dx, 3ceh
       mov     al, 4
       out     dx, al
       inc     dx
       xor     al, al
       out     dx, al
       ; восстанавливаем режим записи и считывания графического контроллера
       dec     dx
       mov     al, 5
       out     dx, al
       inc     dx
       mov     al, 10h
       out     dx, al
       ; восстанавливаем сегмент окна доступа к плоскостям
       dec     dx
       mov     al, 6
       out     dx, al
       inc     dx
       mov     al, 0eh   ; 0b800h, 32Кб
       out     dx, al
       sti
Код не проверял, нацарапал прямо в окне браузера!, так что проверь сам. Перед очередным блоком коментов регистр DX должен содержать либо 3C4, либо 3CF! После первого out он должен увеличиться на еденицу! А то я мог и пропустить Извини за отсутствие нормальных коментариев, сил больше нет, сам разберешься

Вот ещё вариант
Кликните здесь для просмотра всего текста
Цитата Сообщение от Jin X
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
;----------------------------------------------------------------------------;
 
; Процедура GetCharImage - получить образ символа
; Вход: AL = код символа, ES:DI = адрес для записи образа символа (16 байт)
GetCharImage    proc    near
 
                xor     ah,ah
                xchg    si,ax
 
                cli
                mov     dx,3CEh
                mov     ax,0C06h
                out     dx,ax          ; Отвязываем чётную карту от нечётной, Seg=0B800h (P.S. Wow! Как умно сказанул!)
                mov     ax,00204h
                out     dx,ax          ; Выбираем для чтения карту #2
                mov     ax,00005h
                out     dx,ax          ; Регистр режима (НЕ odd/even-адресация и т.д)
 
                push    ds
if              @Cpu and 1
                push    0B800h
                pop     ds
                shl     si,5
else
                mov     cx,0B800h
                mov     ds,cx
                mov     cl,5
                shl     si,cl
endif
                mov     cx,8
                cld
                rep     movsw          ; Копируем образ символа в память
                pop     ds
 
                mov     ax,0E06h
                out     dx,ax          ; Связываем чётную карту с нечётной, Seg=0B800h
                mov     ax,1005h
                out     dx,ax          ; Регистр режима (odd/even-адресация и т.д)
                mov     ax,4
                out     dx,ax          ; Выбираем для чтения карту #0
 
                sti
                ret
 
GetCharImage    endp
 
;----------------------------------------------------------------------------;
 
; Процедура SetCharImage - установить образ символа
; Вход: AL = код символа, DS:SI = адрес образа символа (16 байт)
SetCharImage    proc    near
 
                xor     ah,ah
                xchg    di,ax
 
                cli
                mov     dx,3C4h
                mov     ax,402h
                out     dx,ax          ; Разрешаем запись в плоскость 2
                mov     ax,504h
                out     dx,ax          ; Режим памяти (текстовый, последов, 64K памяти)
                mov     dl,0CEh
                mov     ax,0C06h
                out     dx,ax          ; Отвязываем чётную карту от нечётной, Seg=0B800h
                                       ; (P.S. Wow! Как умно сказанул!)
                push    es
if              @Cpu and 1
                push    0B800h
                pop     es
                shl     di,5
else
                mov     cx,0B800h
                mov     es,cx
                mov     cl,5
                shl     di,cl
endif
                mov     cx,8
                cld
                rep     movsw          ; Копируем образ символа из памяти
                pop     es
 
                mov     ah,0Eh
                out     dx,ax          ; Связываем чётную карту с нечётной
                mov     dl,0C4h
                mov     ax,304h
                out     dx,ax          ; Режим памяти (текстовый, чередующ, расш.пам)
                mov     al,2
                out     dx,ax          ; Запрещаем запись в плоскость 2
 
                sti
                ret
SetCharImage    endp

При работе через прерывания BIOS можно легко получить ситуацию, когда полученный вектор на таблицу знакогенератора указывает на ПЗУ и изменения невозможны. Проверял это и на реальном ПК и в виртуальной машине VirtualBox с FreeDOS без русификатора.
Работая с портами видеокарты - всегда работаете с ОЗУ, поэтому изменения будут.

Надеюсь, что примеров будет достаточно, а дальше, читая описание VGA разберётесь.

Вот ещё ссылка
Замена в знакогенераторе символа "A"
1
Ушел с форума
Автор FAQ
 Аватар для Mikl___
16373 / 7685 / 1080
Регистрация: 11.11.2010
Сообщений: 13,759
25.07.2020, 12:34
Цитата Сообщение от surfgamer Посмотреть сообщение
А никто не знает по каким адресам находятся блоки шрифтов?
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
.model tiny
.code
.386
org 100h
WIDTH_SCREEN    equ 640
 
start:  mov ax,4F02h;VESA 640x480 101h
    mov bx,101h
    int 10h
    mov ax,1010h;установить один регистр цвета
        mov bx,0FFh;номер цвета
        mov dh,3Fh;яркость красного
        mov cx,3F3Fh;яркость зеленого (CH) и синего (CL)
        int 10h
        xor bx,bx
        mov dx,bx
        mov cx,bx
        int 10h
        push 0A000h ; видеосегмент
        pop es
        push 0F000h
        pop gs
        xor di,di   ; левый верхний угол
        mov bx,offset Hello    ; адрес текстовой строки
next:   movzx si,byte ptr [bx]  ; получаем очередной символ из строки Hello
        shl si,3    ; умножаем индекс символа на 8
        jz exit     ; это последний символ?
        add si,0FA6Eh   ; адрес символа в шрифте
        mov cx,8    ; 8 байт на одну букву
@@:     lods byte ptr gs:[si]
    mov ah,al
    rept 8
        add ax,ax;а если бит равен 0 - делаем AL=0
        sbb al,al
        stosb    ;пишем в видеопамять
        endm
    add di,WIDTH_SCREEN - 8; сдвигаемся на следующую строку
        loop @b    
        sub di,8*WIDTH_SCREEN - 8
        inc bx
        jmp next
exit:   mov ah,0
        int 16h
        mov ax,3    ; восстанавливаем текстовый режим
        int 10h
        ret
Hello db "Hello, world!",0
end start
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.07.2020, 12:34
Помогаю со студенческими работами здесь

Замена символа
Здравствуйте!!! помогите решить задачку! Дано строка символов оттуда надо убрать букву "А" и вместо буквы "Е" заменить...

Замена символа
Нужна ваша помощь. Есть переменная $a="123-456-7890"; Нужно привести к виду $a="xxx-xxx-xxxx"; Вот как...

Замена символа \ на \\
Ох ребята... больше не могу. Как в строке заменить символ \ на \\ _Path.Replace(@"",@""); - не работает... если без собаки, пишет...

замена символа
Собственно учу си по манам из инетов, есть вот такой пример #include <stdio.h> void sp_to_dash(const char *str); int main(void)...

Замена символа
Пользователь вводит небольшой текст(хватит и около 200-250 символов), нужно вместо пробела вставить запятую и пробел( вместо " "...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru