Вывод текста в графическом режиме (оптимизация) - Assembler
Формулировка задачи:
Пытаюсь оптимизировать свой набросок для вывода текста в видеорежиме VESA 1280x1024 119h. Визуально все работает, но сравнительно медленно. Цикл
В bochs при скорости виртуального CPU (4 000 000 инструкций/сек.) цикл исполняется порядка 1000-2000 раз.
Хотелось бы выслушать более оптимальные алгоритмы или предложения по совершенствованию существующего. В EDI уже изначально находится LFB. Использую растровый ANSI-шрифт 12x18, отраженный по вертикали вручную.
@@: Mov edx,message2 Call Draw_text Inc dword [counter0] Jmp @b
Use32 Org 400000h Start: Mov edx,message1 Call Draw_text Add edi,20*2560 ;Перенос строки Mov edx,message Call Draw_text Add edi,20*2560 Mov edx,message3 Call Draw_text Add edi,20*2560 @@: Mov edx,message2 Call Draw_text Inc dword [counter0] Jmp @b message db ' Protected mode',0 message1 db ' Пример вывода текста в графическом режиме',0 message2 db ' ЗАДАЧА: ' counter0 dd 11111111 db 0 message3 db ' >: ',0 Draw_text: Pushad Mov eax,edi Mov esi,bitmap-4 ;12x18 @@: Mov bl,byte [edx] Test bl,bl Jz @f Inc edx Inc bl Call Print_sumb Add eax,24 Jmp @b @@: Popad Ret Print_sumb: Pushad iMul ebx,24 ;Смещение символа в таблице Add ebx,34 ;Выравнивание Add esi,ebx Mov edi,eax Xor ebx,ebx print_hr_line: Mov ecx,12 ;Ширина символа @@: Mov ax,word [esi] Test al,al Jz setform Mov word [edi],ax new_pixel: Add esi,2 Add edi,2 Loop @b Add edi,1280*2-24 ;Разрешение экрана+байт/пиксель-24 Add esi,3072*2-24 ;Длина шрифта+байт/пиксель-24 Inc ebx Cmp ebx,18 ;Высота символа Jz @f Jmp print_hr_line @@:Popad Ret setform: Mov ax,011000000000100b Mov word [edi],ax Jmp new_pixel bitmap: file 'font.bmp'
Решение задачи: «Вывод текста в графическом режиме (оптимизация)»
textual
Листинг программы
.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
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д