С Новым годом! Форум программистов, компьютерный форум, киберфорум
ОС на Assembler
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
7 / 6 / 3
Регистрация: 30.03.2020
Сообщений: 123
NASM

[Linux + GRUB] Графика в защищённом режиме

08.08.2020, 14:01. Показов 3096. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем HI, я написал минимальное ядро(или ОС, я хз как правильно, в разных источниках то так, то так), и когда я захожу туда, я могу например в видеопамять по адресу 0xB8000 записывать разные данные, напр. "Hello, world!". Но как можно с графикой работать? Тип видеопамять она в 4000 байт - 80х25х2, каждый символ он по два байта - ASCII-код и свойства. А как мне, например, пиксель под номером NxM раскрасить в зелёный цвет? Или там линию провести? Или квадрат нарисовать? Ну и всё в таком духе. А то я что-то не понимаю.

Добавлено через 1 минуту
Кому интересно, вот код:
kernel.asm
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
[bits 32]
 
section .data
    msg db 'Hello, world!'
 
section .bss
    stack_space resb 8192
 
section .text
 
    align 4
    dd 0x1BADB002            
    dd 0x00                  
    dd - (0x1BADB002 + 0x00)
 
    global _start
 
    extern clear
    extern init
 
_start:
    cli
    mov esp, stack_space
 
    call init
    call clear
 
    ; ???
 
    hlt
kernel.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void init(void) __asm__("init");
 
void clear(void) __asm__("clear");
 
char *vm;
 
void init(void) {
    vm = (char *)0xB8000;
}
 
void clear(void) {
    for (unsigned int i = 0; i < 80 * 25 * 2;) {
        vm[i++] = ' ';
        vm[i++] = 0x07;         
    }
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.08.2020, 14:01
Ответы с готовыми решениями:

Память в защищенном режиме
Всем доброго дня! Я, наконец, сдал основные экзамены и теперь снова могу заняться столь интересным для меня делом!)) Я многое забыл и...

Прерывания в защищенном режиме
Помогите пожалуйста разобраться с прерываниями в защищенном режиме.Какие обращения к памяти есть. Какие ошибки могут быть, есть ли...

Вывод сообщения в защищенном режиме
.386p rmcode segment para public 'CODE' use16 assume cs:rmcode, ds:rmcode, ss:rmstack ...

12
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8647 / 4482 / 1669
Регистрация: 01.02.2015
Сообщений: 13,889
Записей в блоге: 12
08.08.2020, 14:32
В разных графических режимах видеопамять по разному организована - т.е. разные способы изменить цвет точки.
В книге
Касаткин А.И. Управление ресурсами.
приведены следующие варианты

Для видеорежимов 4 и 5
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// L10_2.C
void plot45(int x,int y,int color)
{ register char _es * offset;
  register char mask1, mask2,work, mod4x;
  _ES=0xb800;
  mod4x=(x & 0x03)<<1;
  offset=(char _es*)
         (0x2000*(y & 0x01)+80*(y>>1)+(x>>2));
  mask2=(color & 0x03)<<(6-mod4x);
  work=*offset;
  if(color & 0x80) // если бит 7 равен 1, выполняется XOR
    *offset=work^mask2;
  else             // режим переопределения текущего содержимого
  { mask1=0xc0>>mod4x;
    work= work & ~mask1;
    *offset=work | mask2;
  }
}
Для 6
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// L10_3.C
void plot6(int x, int y, int color)
{ register char _es * offset;
  register char mask1, mask2,work, mod8x;
  mod8x=x & 0x07;
  offset=(char _es*)
         (0x2000*(y & 0x01)+80*(y>>1)+(x>>3));
  mask2=(color & 0x01)<<(7-mod8x);
  _ES=0xb800;
  work=*offset;
  if(color & 0x80) // если бит 7 равен 1, выполняется XOR
    *offset=work^mask2;
  else             // режим переопределения текущего содержимого
  { mask1=0x80>>mod8x;
    work= work & ~mask1;
    *offset=work | mask2;
  }
}
Для 13
C
1
2
3
4
5
6
7
// L10_4.C
void plot13(int x, int y, int color)
{ register char _es * offset;
  offset=320*y+x;
  _ES=0xa000;
  *offset=color;
}
Для 0Dh, 0Eh, 10h-12h
C
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
// L10_5.C
#include "screen.h"
#include <dos.h>
// Функция корректно работает для режимов 0Dh, 0Eh, 10h-12h
int plot(int x, int y, int color)
{ extern int page, put_mode, bytes_per_line,
             bytes_per_page, max_page, max_x, max_y;
  register char _es * offset;
  register int mask;
  // Проверка допустимости параметров
  if (x<0 || x>max_x || y<0 || y>max_y || page>max_page)
    return BAD_PARAM;
  // Вычисление смещения адреса, содержащего нужный пиксел
  offset=(char _es *)
         (page*bytes_per_page+y*bytes_per_line+(x>>3));
  // Формирование и запись в регистр 8 секвенсора битовой маски
  mask=0x80>>(x&0x07);
  _DX=0x3ce;
  outportb(_DX,8);
  _DX++;
  outportb(_DX,mask);
  _DX--;
  // Задание способа комбинации битов регистров-защёлок и данных из
  // центрального процессора
  outportb(_DX,3);
  _DX++;
  outportb(_DX,put_mode);
  // Задание регистра маски карты
  _DX=0x3c4;
  outportb(_DX,2);
  _DX++;
  outprtb(_DX,0x0f);
  _DX--;
  // Заполнение регистров-защёлок чтением видеобуфера
  _ES=0xa000;
  _AL=*offset;
  // "Сброс" в регистрах-защёлках битов, выбранных регистрами масок
  *offset=0;
  // Запись в регистр маски карты кода цвета пиксела
  outportb(_DX,2);
  _DX++;
  outportb(_DX,color);
  _DX--;
  // Запись цвета color в выбранные масками биты регистров-защёлок
  *offset=0xff;
  // Восстановление адаптера в состояние, ожидаемое BIOS;
  // регистр маски карты равен 0x0f; регистр битовой маски равен 0xff;
  // способ комбинации - переопределение
  outportb(_DX,2);
  _DX++;
  outportb(_DX,0x0f);
  _DX=0x3ce;
  outportb(_DX,8);
  _DX++;
  outportb(_DX,0xff);
  _DX--;
  outportb(_DX,3);
  _DX++;
  outportb(_DX,0x00);
  return OK;
}
Для 0Dh, 0Eh, 10h-12h
C
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
// L10_6.C
#include "screen.h"
#include <dos.h>
// Функция корректно работает для режимов 0Dh, 0Eh, 10h-12h
// Это улучшенный вариант L10_5.C
int plot(int x, int y, int color)
{ extern int page, put_mode, bytes_per_line,
             bytes_per_page, max_page, max_x, max_y;
  register char _es * offset;
  register int mask;
  // Проверка допустимости параметров
  if (x<0 || x>max_x || y<0 || y>max_y || page>max_page)
    return BAD_PARAM;
  // Вычисление смещения адреса, содержащего нужный пиксел
  offset=(char _es *)
         (page*bytes_per_page+y*bytes_per_line+(x>>3));
  // Формирование и запись в регистр 8 секвенсора битовой маски
  mask=0x80>>(x&0x07);
  _AX=(mask<<8) | 0x08;
  _DX=0x3ce;
  asm out dx,ax
  // Задание способа комбинации битов регистров-защёлок и данных из
  // центрального процессора
  _AX=(put_mode<<8) | 0x03;
  asm out dx,ax
  // Задание регистра маски карты
  _DX=0x3c4;
  _AX=0x0f02;
  asm out dx,ax
  // Заполнение регистров-защёлок чтением видеобуфера
  _ES=0xa000;
  _AL=*offset;
  // "Сброс" в регистрах-защёлках битов, выбранных регистрами масок
  *offset=0;
  // Запись в регистр маски карты кода цвета пиксела
  _AX=(color<<8) | 0x02;
  asm out dx,ax
  // Запись цвета color в выбранные масками биты регистров-защёлок
  *offset=0xff;
  // Восстановление адаптера в состояние, ожидаемое BIOS;
  // регистр маски карты равен 0x0f; регистр битовой маски равен 0xff;
  // способ комбинации - переопределение
  _AX=0x0f02;
  asm out dx,ax
  _DX=0x3ce;
  _AX=0x0f08;
  asm out dx,ax
  _AX=0x0003;
  asm out dx,ax
  return OK;
}
Для режимов VESA на точку выделяют 4 байта, из которых 3 - это RGB компоненты, а четвёртый не используется - он для выравнивания.

Режимы VESA имеют большие размеры экрана, которые не умещаются в один сегмент памяти 16-разрядного режима. Поэтому с ними работают или средствами VESA BIOS через "окно" или в unreal режиме или в защищённом.
0
7 / 6 / 3
Регистрация: 30.03.2020
Сообщений: 123
08.08.2020, 14:38  [ТС]
Я хочу использовать 13. Вопрос: Что это за запись:
Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
register char _es * offset;
?
Первый раз вижу. Догадываюсь, что offset это регистр es чтоли? Что вообще эта функция делает и, можно ли её на ассемблерее сделать, потому-что если используется регистр(да и функция короткая), не проще было бы на NASM-е реализовать?

Добавлено через 3 минуты
Я кстати что-то не понимаю - зачем там вообще es используется? можете привести ассемблерный аналог, пожалуйста
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8647 / 4482 / 1669
Регистрация: 01.02.2015
Сообщений: 13,889
Записей в блоге: 12
08.08.2020, 14:45
Весь тот код для DOS и 16 разрядный режим. Т.е. напрямую он не подойдёт, т.к. ваш код, похоже, работает в защищённом режиме. Т.е. всё это просто иллюстрация.

Исходя из общих представлений, в строке
C
3
{ register char _es * offset;
объявляется переменная offset, которая будет указывать смещение относительно регистра ES, т.е. объявляется указатель es:offset
Не очень понимаю, как у вас устроена память, но похоже, что переводится это
C
1
2
3
char *vm;
    vm = (char *)0xa0000;
    vm[320*y+x]=color;
0
7 / 6 / 3
Регистрация: 30.03.2020
Сообщений: 123
08.08.2020, 14:51  [ТС]
Спасибо, сейчас попробую

Добавлено через 1 минуту
P.S. Переключится это же
Assembler
1
2
mov ax, 0xE
int 0x10
?

Добавлено через 2 минуты
Не работает(
При заходе сразу же перезагрузка начинается

Добавлено через 29 секунд
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
[bits 32]
 
section .data
    msg db 'Hello, world!'
 
section .bss
    stack_space resb 8192
 
section .text
 
    align 4
    dd 0x1BADB002            
    dd 0x00                  
    dd - (0x1BADB002 + 0x00)
 
    global _start
 
    extern clear
    extern init
    extern draw_pixel
 
_start:
    cli
    mov esp, stack_space
 
    call init
    call clear
 
    mov ax, 0xE
    int 0x10
 
    push 100
    push 100
    push 100
    call draw_pixel
    add esp, 12
 
    hlt
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void init(void) __asm__("init");
 
void clear(void) __asm__("clear");
 
void draw_pixel(int x, int y, int color) __asm__("draw_pixel");
 
char *vm;
 
void init(void) {
    vm = (char *)0xB8000;
}
 
void clear(void) {
    for (unsigned int i = 0; i < 80 * 25 * 2;) {
        vm[i++] = ' ';
        vm[i++] = 0x07;         
    }
}
 
void draw_pixel(int x, int y, int color) {
    vm[y * 320 + x] = color;
}
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8647 / 4482 / 1669
Регистрация: 01.02.2015
Сообщений: 13,889
Записей в блоге: 12
08.08.2020, 14:53
Вряд ли. Вы же в защищённом режиме - там процедуры BIOS уже не работают.
Ищите, как переключать напрямую, программируя CRTC.

Поищите про VESA режимы. Они работают с защищённым режимом через BIOS, только там нужны дополнительные манипуляции по поиску "точки входа".

Добавлено через 1 минуту
Похоже, дальше я вам уже не помогу - не интересовался системным программированием в защищённом режиме.
1
7 / 6 / 3
Регистрация: 30.03.2020
Сообщений: 123
08.08.2020, 14:57  [ТС]
И на том спасибо
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8647 / 4482 / 1669
Регистрация: 01.02.2015
Сообщений: 13,889
Записей в блоге: 12
08.08.2020, 18:32
По ссылке тезисами поясняются графические возможности разработчика, "попавшего" в защищённый режим
https://wiki.osdev.org/Drawing_In_Protected_Mode
https://files.osdev.org/mirror... /index.htm
Там же приводится пример кода на C по переключению VGA видеорежимов при помощи программирования CRTC
https://files.osdev.org/mirror... cs/modes.c
0
10.08.2020, 12:22

Не по теме:

Tapacuk, Вы на виртуальной машине экспериментируете или на ноутбуке с FreeDOS ?

0
7 / 6 / 3
Регистрация: 30.03.2020
Сообщений: 123
20.08.2020, 15:11  [ТС]
Да, задавал, но как я понял интеррупты у меня не работают (в защищёнке) так что я не знаю как рисовать - может другой ответ найдётся
0
7 / 6 / 3
Регистрация: 30.03.2020
Сообщений: 123
21.08.2020, 12:04  [ТС]
На виртуалке
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
24.08.2020, 06:16
Цитата Сообщение от Tapacuk Посмотреть сообщение
Тип видеопамять она в 4000 байт - 80х25х2, каждый символ он по два байта - ASCII-код и свойства. А как мне, например, пиксель под номером NxM раскрасить в зелёный цвет? Или там линию провести? Или квадрат нарисовать?
Чтобы рисовать квадрат по пикселям, нужно знать, по каким физическим адресам располгается массив пикселей, как он организован, и какой формат самих пикселей ( в каких битах какие компоненты цвета хранятся ).
Например, в гипотетическом режиме 1200x768x32 на каком-нибудь устройстве фреймбуфер мог бы быть устроен, например, так:
C++
1
2
3
using pixel=uint32_t;
 
extern pixel frame_buffer[768][1280];
где последние 80 каждой строки не отображаются на экране.

Мы можем просто знать, где распологается видеобуфер в физическом адресном пространстве конкретного устройства, и как он устроен.
Мы можем получить эту информацию от firmware, напр. через функции GOP от UEFI, или функции VESA в режиме CSM или BIOS без UEFI.
Можно, наконец, изучить существующий драйвер, и использовать в своих целях.
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
25.03.2021, 11:29
Старые примеры рисования линии по точкам в multiboot-коде, запущенном из GRUB или другого совместимого загрузчика есть в документации GNU GRUB(2)
https://www.gnu.org/software/g... 002ec.html
https://www.gnu.org/software/g... 002ec.html
Режим должен быть установлен самим загрузчиком.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.03.2021, 11:29
Помогаю со студенческими работами здесь

Программирование видеокарты в защищённом режиме
Перерыл пол инета, не нашел ничего. начал изучать assembler не очень давно. книги по программированию видеокарт очень старые. может кто...

Не обрабатываются прерывания в защищенном режиме
Здравствуйте! Помогите, пожалуйста, найти и исправить ошибку. Программа должна переводить процессор в защищенный режим и обрабатывать...

Особые случаи в защищённом режиме
Какие особые случаи и при каких условиях могут возникнуть при выполнении команды FAR JMP dword ptr в защищённом режиме

Размер программы в защищенном режиме
и снова возникли проблемы. Дело в том,что при достижении определенного размера программы,она перестает работать,а порою работает с...

Работа с файлами в защищенном режиме
Здравствуйте, я взялся писать ОС, уже готов загрузчик переводящий в защищенный режим процессор, IDT GDT разумеется тоже. Хотелось бы...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru