Page 2 of 2
Re: I know a very optimized way to print characters in pmode
Posted: Fri Nov 11, 2011 2:52 am
by rdos
Why are such simple things so hard in C?
Code: Select all
mov ax,730h
mov edi,0B8000h
mov [edi],ax ; will write "0" in top left corner
Re: I know a very optimized way to print characters in pmode
Posted: Fri Nov 11, 2011 2:59 am
by Solar
rdos wrote:Why are such simple things so hard in C?
Because your ASM example doesn't do the same thing (printing a
parameterized character to a
parameterized location).
Moreover, your ASM source is specific to a certain assembler, and won't necessarily compile on a different one (AT&T vs. Intel syntax). The C source discussed here would compile on
any C compiler.
Re: I know a very optimized way to print characters in pmode
Posted: Fri Nov 11, 2011 4:02 am
by rdos
Solar wrote:Because your ASM example doesn't do the same thing (printing a
parameterized character to a
parameterized location).
That's easy to fix:
Code: Select all
; AH = attribute
; AL = char
; BL = row
; BH = col
WriteChar Proc
push edi
push ax
mov al,80
mul bl
add al,bh
adc ah,0
add ax,ax
mov edi,0B8000h
or di,ax
pop ax
mov [edi],ax
pop edi
ret
WriteChar Endp
Solar wrote:Moreover, your ASM source is specific to a certain assembler, and won't necessarily compile on a different one (AT&T vs. Intel syntax). The C source discussed here would compile on
any C compiler.
Yes, but it is unreadable.
BTW, if you also want a version that is independent of the physical location of the video-buffer, and that have forecolor and backcolor as parameters instead of the combined attribute, it looks something like this:
Code: Select all
; AL Char
; BL Fore color
; BH Back color
; CX Column
; DX Row
WriteChar Proc
push ds
push ax
push di
mov ah,bh
shl ah,4
or ah,bl
push ax
push dx
mov ax,80
mul dx
add ax,cx
add ax,ax
mov di,ax
mov ax,dosb800
mov ds,ax
pop dx
pop ax
mov [di],ax
pop di
pop ax
pop ds
ret
WriteChar Endp
Re: I know a very optimized way to print characters in pmode
Posted: Fri Nov 11, 2011 4:21 am
by rdos
berkus wrote:rdos wrote:Yes, but it is unreadable.
It's unreadable because it was written in a pretty lame way. See Solar's improvement, which is heaps more readable.
Well, it consists of a set of unreadable macros instead. There is nothing more frustrating than to try to figure out how a particular #define is evaluated by the compiler when these are generated based on a zillion other defines.
Re: I know a very optimized way to print characters in pmode
Posted: Fri Nov 11, 2011 4:31 am
by Combuster
The fact that you suck at chinese doesn't make it a bad thing that there are a billion people out there fluent with it.
You're breaking the language war rule, stop it please.
Re: I know a very optimized way to print characters in pmode
Posted: Fri Nov 11, 2011 4:58 am
by Solar
rdos wrote:berkus wrote:rdos wrote:Yes, but it is unreadable.
See Solar's improvement, which is heaps more readable.
Well, it consists of a set of unreadable macros instead.
Neither "unreadable" nor "a set" (since there is only one macro), hence I call "troll".
If all you have is a hammer, a screw is just a funny-looking and somewhat impractical nail...
Re: I know a very optimized way to print characters in pmode
Posted: Fri Nov 11, 2011 5:41 am
by Brendan
Hi,
Solar wrote:I took the liberty of optimizing your code further:
This version suffers from the same problem as the original - it fails to recognise that often you're printing a string and you only need to do the "address = start + (y * 80 + x) * 2" calculation once for the first character, then "address += 2" for each additional character. Basically, the next step in optimisation is to realise "putch()" is virtually irrelevant because you're using "putstring()" for almost everything instead.
The first step in optimising "putstring()" is to just append the new string to a buffer while checking if it contains any '\n' characters. If it does you'd copy whole lines (and never partial lines) to display memory. Basically "putstring()" would call a "putline(int y, char *string)" function that does "address = start + y * 80 * 2" for the first character and then "address += 2" for the remaining characters (or maybe a "lodsb; stosw" loop).
The next step would be to realise that this causes excessive scrolling. For example, if you add 12 lines of text at once, then you scroll 12 times (by 1 line each time) instead of only scrolling once (by 12 lines). To fix that you add a "flush_console()" function. The "putstring()" function just appends data to the buffer, and "flush_console()" counts how many lines are in the buffer, scrolls the screen once (if necessary), then copies text from the buffer to the screen.
Cheers,
Brendan
Re: I know a very optimized way to print characters in pmode
Posted: Fri Nov 11, 2011 6:12 am
by Solar
Agreed.
My "optimization" was aiming at a proof that proper use of constants doesn't mean an increase in executable size. (Plus some implied hints to coding style).
As Karlosoft pointed out, the clrscr() function could be replaced by a memset() call, and you pointed out some valid issues with the underlying algorithm.
All in all, I would think twice before implementing either putch() or putstring() or whatever. Chances are you'll want to use <stdio.h>-like functionality sooner or later, and that doesn't need either putch() or putstring(), but a backend for plain old write( 1, ... ), i.e. a memcpy() capable of handling linefeeds...