Hi,
I am trying to write a string to the video memory. I can get
individual characters to the screen without a problem, as shown in my
code:
-------------------------------------------------------------------------
START:
MOV AX, 0xB800 ;Video memory
MOV ES, AX ;Move to a segment
XOR DI, DI ;Offset (B800:0000)
MOV AX, 'T' ;ASCII Character to print
CALL WRMEM ;Procedure to write it to memory and set colour
MOV AX, 'E'
CALL WRMEM
MOV AX, 'S'
CALL WRMEM
MOV AX, 'T'
CALL WRMEM
HANG: ;End of program
JMP HANG
WRMEM:
STOSB ;Write the byte to memory and INC DI (to the next offset)
MOV AX, 7 ;Set colour - white on black
STOSB ;write colour to memory and INC DI
RET ;Return
----------------------------------------------------------------------------------
The problem is that it is a really stupid way to write a sentence to
the screen. I want to use this in a 'kernel' that is loaded by a boot
loader, which is why I am trying to write directly to video memory.
I have tried 'msg db "message"' and 'mov si, msg' and lodsb, but for
some reason I can't get it to work. Am I on the right track?
|
|
0
|
|
|
|
Reply
|
spamtrap2 (1628)
|
2/7/2007 2:15:37 AM |
|
On 6 Feb 2007 18:15:37 -0800, "Luke" <spamtrap@crayne.org> wrote in
comp.lang.asm.x86:
> Hi,
>
> I am trying to write a string to the video memory. I can get
> individual characters to the screen without a problem, as shown in my
> code:
>
> -------------------------------------------------------------------------
> START:
> MOV AX, 0xB800 ;Video memory
> MOV ES, AX ;Move to a segment
> XOR DI, DI ;Offset (B800:0000)
>
> MOV AX, 'T' ;ASCII Character to print
> CALL WRMEM ;Procedure to write it to memory and set colour
> MOV AX, 'E'
> CALL WRMEM
> MOV AX, 'S'
> CALL WRMEM
> MOV AX, 'T'
> CALL WRMEM
>
> HANG: ;End of program
> JMP HANG
>
> WRMEM:
> STOSB ;Write the byte to memory and INC DI (to the next offset)
> MOV AX, 7 ;Set colour - white on black
> STOSB ;write colour to memory and INC DI
> RET ;Return
> ----------------------------------------------------------------------------------
>
>
> The problem is that it is a really stupid way to write a sentence to
> the screen. I want to use this in a 'kernel' that is loaded by a boot
> loader, which is why I am trying to write directly to video memory.
> I have tried 'msg db "message"' and 'mov si, msg' and lodsb, but for
> some reason I can't get it to work. Am I on the right track?
It has been a very long time since I did this, and I'm doing it from
memory, so it might be not quite right, but:
msg: db 'test
db 0 ; so you know when to stop
write_screen:
mov ax, 0b800h
mov es, ax
xor di, di
mov si, msg ; point to string
mov ah, 7 ; attribute to use, could be from a variable
cld
write_loop:
lodsb ; get string character into al
or al, al ; check for 0, end of string
jz write_done
stosw ; write character and attribute
jmp write_loop
write_done:
; whatever you want to do next
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
|
|
0
|
|
|
|
Reply
|
Jack
|
2/7/2007 6:23:24 AM
|
|
Luke wrote:
> Hi,
>
> I am trying to write a string to the video memory. I can get
> individual characters to the screen without a problem, as shown in my
> code:
[snip]
> The problem is that it is a really stupid way to write a sentence to
> the screen. I want to use this in a 'kernel' that is loaded by a boot
> loader, which is why I am trying to write directly to video memory.
> I have tried 'msg db "message"' and 'mov si, msg' and lodsb, but for
> some reason I can't get it to work. Am I on the right track?
Yes, but it would also help if you showed us the code that didn't work.
Does it set up DS?
Two unrelated issues are where you set up the direction flag and why you
always load the entire AX register when you never use AH.
Bjarni
--
INFORMATION WANTS TO BE FREE
|
|
0
|
|
|
|
Reply
|
Bjarni
|
2/7/2007 6:41:10 AM
|
|
On 7 helmi, 04:15, "Luke" <spamt...@crayne.org> wrote:
> Hi,
>
> I am trying to write a string to the video memory. I can get
> individual characters to the screen without a problem, as shown in my
> code:
>
> -------------------------------------------------------------------------
> START:
> MOV AX, 0xB800 ;Video memory
> MOV ES, AX ;Move to a segment
> XOR DI, DI ;Offset (B800:0000)
>
> MOV AX, 'T' ;ASCII Character to print
> CALL WRMEM ;Procedure to write it to memory and set colour
> MOV AX, 'E'
> CALL WRMEM
> MOV AX, 'S'
> CALL WRMEM
> MOV AX, 'T'
> CALL WRMEM
>
> HANG: ;End of program
> JMP HANG
>
> WRMEM:
> STOSB ;Write the byte to memory and INC DI (to the next offset)
> MOV AX, 7 ;Set colour - white on black
> STOSB ;write colour to memory and INC DI
> RET ;Return
> ----------------------------------------------------------------------------------
>
> The problem is that it is a really stupid way to write a sentence to
> the screen. I want to use this in a 'kernel' that is loaded by a boot
> loader, which is why I am trying to write directly to video memory.
> I have tried 'msg db "message"' and 'mov si, msg' and lodsb, but for
> some reason I can't get it to work. Am I on the right track?
What about this:
START:
MOV AX, 0xB800
MOV ES, AX
XOR DI, DI
CALL WRMEM
HANG:
JMP HANG
WRMEM:
mov si, offset msg
mov cx, 4 ; len of msg
mov ah, 07h ; color attr
write:
lodsb ; get char from msg and inc si
stosw ; write char and attr
loop write ; while there's text
ret
msg db 'test'
|
|
0
|
|
|
|
Reply
|
KJH
|
2/7/2007 6:52:17 AM
|
|
Luke wrote:
> Hi,
>
> I am trying to write a string to the video memory. I can get
> individual characters to the screen without a problem, as shown in my
> code:
>
> -------------------------------------------------------------------------
> START:
> MOV AX, 0xB800 ;Video memory
> MOV ES, AX ;Move to a segment
> XOR DI, DI ;Offset (B800:0000)
>
> MOV AX, 'T' ;ASCII Character to print
> CALL WRMEM ;Procedure to write it to memory and set colour
> MOV AX, 'E'
> CALL WRMEM
> MOV AX, 'S'
> CALL WRMEM
> MOV AX, 'T'
> CALL WRMEM
>
> HANG: ;End of program
> JMP HANG
>
> WRMEM:
> STOSB ;Write the byte to memory and INC DI (to the next offset)
> MOV AX, 7 ;Set colour - white on black
> STOSB ;write colour to memory and INC DI
> RET ;Return
> ----------------------------------------------------------------------------------
>
>
> The problem is that it is a really stupid way to write a sentence to
> the screen. I want to use this in a 'kernel' that is loaded by a boot
> loader, which is why I am trying to write directly to video memory.
> I have tried 'msg db "message"' and 'mov si, msg' and lodsb, but for
> some reason I can't get it to work. Am I on the right track?
Yes. You've set es to "screen memory". What about ds? If it's a dos .com
file, ds will be set to the proper value to find "msg" when dos loads
it. From boot, this may not be true, unless you've made it so. That's a
likely cause of the problem. If this is in the bootsector, 0000:7Cxxh or
07C0h:00xxh should be right (the former if assembled at "org 7C00h"). If
this is something you've loaded from your bootsector, presumably you
know where you loaded it...
Best,
Frank
|
|
0
|
|
|
|
Reply
|
Frank
|
2/7/2007 7:50:31 AM
|
|
"Luke" <spamtrap@crayne.org> writes:
> Hi,
>
> I am trying to write a string to the video memory. I can get
> individual characters to the screen without a problem, as shown in my
> code:
>
> -------------------------------------------------------------------------
> START:
> MOV AX, 0xB800 ;Video memory
> MOV ES, AX ;Move to a segment
> XOR DI, DI ;Offset (B800:0000)
>
> MOV AX, 'T' ;ASCII Character to print
> CALL WRMEM ;Procedure to write it to memory and set colour
> MOV AX, 'E'
> CALL WRMEM
> MOV AX, 'S'
> CALL WRMEM
> MOV AX, 'T'
> CALL WRMEM
>
> HANG: ;End of program
> JMP HANG
>
> WRMEM:
> STOSB ;Write the byte to memory and INC DI (to the next offset)
> MOV AX, 7 ;Set colour - white on black
> STOSB ;write colour to memory and INC DI
> RET ;Return
> ----------------------------------------------------------------------------------
>
>
> The problem is that it is a really stupid way to write a sentence to
> the screen. I want to use this in a 'kernel' that is loaded by a boot
> loader, which is why I am trying to write directly to video memory.
> I have tried 'msg db "message"' and 'mov si, msg' and lodsb, but for
> some reason I can't get it to work. Am I on the right track?
Yes, but if you want to copy a memory block to the video RAM like
that, you should either write a function that will copy the string to
a buffer containing each character and its color: 'm',7,'e',7,'s',7,...
or write the string like that in the first place.
--
__Pascal Bourguignon__ http://www.informatimago.com/
COMPONENT EQUIVALENCY NOTICE: The subatomic particles (electrons,
protons, etc.) comprising this product are exactly the same in every
measurable respect as those used in the products of other
manufacturers, and no claim to the contrary may legitimately be
expressed or implied.
|
|
0
|
|
|
|
Reply
|
Pascal
|
2/7/2007 10:33:39 AM
|
|
On 6 Feb 2007 18:15:37 -0800, "Luke" <spamtrap@crayne.org> wrote:
>Hi,
>
>I am trying to write a string to the video memory. I can get
>individual characters to the screen without a problem, as shown in my
>code:
>
>-------------------------------------------------------------------------
>START:
> MOV AX, 0xB800 ;Video memory
> MOV ES, AX ;Move to a segment
> XOR DI, DI ;Offset (B800:0000)
>
> MOV AX, 'T' ;ASCII Character to print
> CALL WRMEM ;Procedure to write it to memory and set colour
> MOV AX, 'E'
> CALL WRMEM
> MOV AX, 'S'
> CALL WRMEM
> MOV AX, 'T'
> CALL WRMEM
>
>HANG: ;End of program
> JMP HANG
>
>WRMEM:
> STOSB ;Write the byte to memory and INC DI (to the next offset)
> MOV AX, 7 ;Set colour - white on black
> STOSB ;write colour to memory and INC DI
> RET ;Return
>----------------------------------------------------------------------------------
>
>
>The problem is that it is a really stupid way to write a sentence to
>the screen. I want to use this in a 'kernel' that is loaded by a boot
>loader, which is why I am trying to write directly to video memory.
>I have tried 'msg db "message"' and 'mov si, msg' and lodsb, but for
>some reason I can't get it to work. Am I on the right track?
>
I think what you are looking for here is LODSB.
You first set DS:SI to point to the string you want to
write, just as you now set ES:DI to the destination.
Then your main loop would be:
WRITE_STRING:
LODSB
TEST AL,AL
JZ DONE
CALL WRMEM
JMP WRITE_STRING
DONE:
But this can be improved upon, since only AL
is needed to write the character. So set AH = 7
before the loop, and replace the call to
WRMEM with STOSW.
Note that the test for AL = 0 is an implementation
of the standard method of null-terminated strings.
Alternatively, if you set the length of the string in CX
you could use a conventional LOOP here.
Hope this helps!
Bob Masta
D A Q A R T A
Data AcQuisition And Real-Time Analysis
www.daqarta.com
Scope, Spectrum, Spectrogram, Signal Generator
Science with your sound card!
|
|
0
|
|
|
|
Reply
|
NoSpam
|
2/7/2007 1:36:59 PM
|
|
"Luke" <spamtrap@crayne.org> wrote in message
news:1170814537.308062.165550@h3g2000cwc.googlegroups.com...
> Hi,
>
> I am trying to write a string to the video memory. I can get
> individual characters to the screen without a problem, as shown in my
> code:
>
> -------------------------------------------------------------------------
> START:
> MOV AX, 0xB800 ;Video memory
> MOV ES, AX ;Move to a segment
> XOR DI, DI ;Offset (B800:0000)
>
> MOV AX, 'T' ;ASCII Character to print
> CALL WRMEM ;Procedure to write it to memory and set colour
> MOV AX, 'E'
> CALL WRMEM
> MOV AX, 'S'
> CALL WRMEM
> MOV AX, 'T'
> CALL WRMEM
>
> HANG: ;End of program
> JMP HANG
>
> WRMEM:
> STOSB ;Write the byte to memory and INC DI (to the next offset)
> MOV AX, 7 ;Set colour - white on black
> STOSB ;write colour to memory and INC DI
> RET ;Return
> ----------------------------------------------------------------------------------
>
>
> The problem is that it is a really stupid way to write a sentence to
> the screen. I want to use this in a 'kernel' that is loaded by a boot
> loader, which is why I am trying to write directly to video memory.
> I have tried 'msg db "message"' and 'mov si, msg' and lodsb, but for
> some reason I can't get it to work. Am I on the right track?
If you can't get it to work you're on the wrong track.
But: the things you tried sound about right. Why didn't it work? You must've
done something else wrong. Perhaps your DS seg was in some random state (as
in ES:DI, the correct pair is DS:SI).
By the by. A subroutine to write a single character is not a really stupid
way, it's just that you usually also should have a subroutine that wraps a
complete string write :o)
[Jongware]
|
|
0
|
|
|
|
Reply
|
Jongware
|
2/7/2007 2:57:00 PM
|
|
Thanks for your code, it looks good, but I am having a problem with
the 'mov si, offset msg' line
when I run 'nasm videomem.asm -o loader.bin', it gives the error
'videomem.asm:11: error: comma or end of line expected'.
I have tried removing the 'offset' from the line, and the error goes
away, but then when running the program, it prints random characters
on the screen. Presumably this is because it doesn't have the correct
DS:SI location and is printing random junk from memory.
This is probably really simple, but I don't have enough experience
behind me... any ideas?
Thanks
|
|
0
|
|
|
|
Reply
|
Luke
|
2/7/2007 11:36:59 PM
|
|
In article <1170814537.308062.165550@h3g2000cwc.googlegroups.com>,
spamtrap@crayne.org says...
> Hi,
>
> I am trying to write a string to the video memory. I can get
> individual characters to the screen without a problem, as shown in my
> code:
..data
current_x db 0
current_y db 0
current_attr db 7
..data?
columns db ?
putstring proc uses es di
; call with ds:si = address of ASCIIZ string to print out.
; uses: di, cx, dx
; The following section takes a pair of coordinates and figures
; out their address.
mov cx,0b000h ; First get the video buffer segment.
mov ah, 0fh
int 10h
mov columns,ah
cmp al, 7
jz @f
mov cx, 0b800h
@@:
mov es,cx
mov al,current_y
mov dl,ah
mul dl
mov di,ax
mov al,current_x
cbw
add di,ax
shl di, 1
; This next bit actually writes the string to the screen.
mov ah,current_attr
lodsb
@@:
stosw
lodsb
test al,al
jnz @b
; This converts the final address back to a pair of coordinates
; and stores them so the next string will immediately follow this
; one if the current position isn't repositioned beforehand.
mov dl, columns
div dl
mov current_y, al
mov current_x, ah
done:
ret
putstring endp
Note that this code is quite old -- at least in theory, simpler
sequences would probably be faster on a modern processor. OTOH, the
speed will usually be limited by the bandwidth to video memory in any
case, so it may be best to just keep it small.
--
Later,
Jerry.
The universe is a figment of its own imagination.
|
|
0
|
|
|
|
Reply
|
Jerry
|
2/8/2007 1:06:22 AM
|
|
Jerry Coffin wrote:
> In article <1170814537.308062.165550@h3g2000cwc.googlegroups.com>,
> spamtrap@crayne.org says...
>
>>Hi,
>>
>>I am trying to write a string to the video memory. I can get
>>individual characters to the screen without a problem, as shown in my
>>code:
>
>
> .data
> current_x db 0
> current_y db 0
> current_attr db 7
>
> .data?
> columns db ?
>
> putstring proc uses es di
> ; call with ds:si = address of ASCIIZ string to print out.
> ; uses: di, cx, dx
> ; The following section takes a pair of coordinates and figures
> ; out their address.
>
> mov cx,0b000h ; First get the video buffer segment.
> mov ah, 0fh
> int 10h
> mov columns,ah
> cmp al, 7
> jz @f
> mov cx, 0b800h
> @@:
> mov es,cx
>
> mov al,current_y
> mov dl,ah
> mul dl
> mov di,ax
> mov al,current_x
> cbw
Would this work properly in 132-column modes?
> add di,ax
> shl di, 1
>
> ; This next bit actually writes the string to the screen.
> mov ah,current_attr
> lodsb
> @@:
> stosw
> lodsb
> test al,al
> jnz @b
>
> ; This converts the final address back to a pair of coordinates
> ; and stores them so the next string will immediately follow this
> ; one if the current position isn't repositioned beforehand.
> mov dl, columns
> div dl
What are we dividing here? Don't we need a "mov ax, di"/"shr ax, 1"
before this?
> mov current_y, al
> mov current_x, ah
> done:
> ret
> putstring endp
>
> Note that this code is quite old
Yeah, we don't see much mode 7 these days! :)
Oh, and don't feed it a null string!
Best,
Frank
|
|
0
|
|
|
|
Reply
|
Frank
|
2/8/2007 5:27:00 AM
|
|
Luke wrote:
> Thanks for your code, it looks good, but I am having a problem with
> the 'mov si, offset msg' line
That's Masm/Tasm syntax - "true Intel syntax". Just remove "offset" for
Nasm.
> when I run 'nasm videomem.asm -o loader.bin', it gives the error
> 'videomem.asm:11: error: comma or end of line expected'.
> I have tried removing the 'offset' from the line, and the error goes
> away, but then when running the program, it prints random characters
> on the screen. Presumably this is because it doesn't have the correct
> DS:SI location and is printing random junk from memory.
Seems likely.
> This is probably really simple, but I don't have enough experience
> behind me... any ideas?
Get some experience behind you? :)
The name "loader.bin" suggests "where we're at". Presumably, you loaded
this from a bootsector, presumably using int 13h, and jumped to it. AS I
recall, this writes to es:bx. Probably, bx was 0 and es had, say,
"LOADER_SEG" in it... Then you did a far jump... "jmp LOADER_SEG:0", or
maybe a far ret(?).
When we get to executing "loader.bin", cs has got the "right" segment in
it (or we wouldn't be there). "push cs"/"pop ds" ought to take care of
ds. Now, "mov si, msg"... Nasm, of course, replaces "msg" with a number
- calculated by "origin" plus "file offset".
I've been known to write similar code - using the same name - which, in
the bootsector, loaded "loader.bin" to LOADER_SEG:100h and made ds =
LOADER_SEG, put an "int 19h" at LOADER_SEG:0, pushed a 0 on the stack,
before the "jmp LOADER_SEG:100h"... The starting conditions for
"loader.bin" were similar to a dos .com file, so I could test code under
dos without having to boot to test it. Didn't help that much, IIRC. If
you've encountered code like that, "loader.bin" wants to be assembled at
"org 100h" (and will exit... well, restart... with a "ret").
Otherwise, I would expect probably "org 0" (although Nasm defaults to
it, I'd specify it "for clarity"). All sorts of other arrangements are
possible, of course. If we need to see the code, we'll probably need to
see the code that loads it, too...
To help you work out how ds, "org", and offset relate, consider these
dos .com files (untested and prone to typos).
org 100h
mov dx, msg ; "offset msg" for Masm/Tasm
mov ah, 9
int 21h
ret
msg db "Hello, World$"
Works (I hope). But suppose we forgot "org 100h", or didn't want it for
some reason. Garbage characters! But we could do:
mov dx, msg + 100h
mov ah, 9
int 21h
ret
msg db "Hello, World$"
Or we could fix up ds so our data *was* at "org 0" with respect to ds:
mov ax, ds
add ax, 10h
mov ds, ax
mov dx, msg ; "offset msg" for Masm/Tasm
mov ah, 9
int 21h
ret
msg db "Hello, World$"
Diddle with those things in your code and I think you'll get it working.
You really are on the right track.
Best,
Frank
|
|
0
|
|
|
|
Reply
|
Frank
|
2/8/2007 9:22:33 AM
|
|
I am using a sample bootsector I got from the web for the moment. I
will be using my own eventually. I have included the relevant part of
the source below.
I am guessing that I need to use ORG 50h, as that's where the kernel
is being loaded?
Long story short, I tried org 50h and org 100h, and it displays a few
garbage characters at seemingly random places on the screen. Should I
be using ORG something else, or is something else the problem?
I have included the source for loader.bin below the boot sector
bootsector (partial)
-------------------------------
; read image file into memory (0050:0000)
mov si, msgCRLF
call DisplayMessage
mov ax, 0x0050
mov es, ax ; destination for
image
mov bx, 0x0000 ; destination for
image
push bx
LOAD_IMAGE:
mov ax, WORD [cluster] ; cluster to read
pop bx ; buffer to read into
call ClusterLBA ; convert cluster to
LBA
xor cx, cx
mov cl, BYTE [SectorsPerCluster] ; sectors to read
call ReadSectors
push bx
; compute next cluster
mov ax, WORD [cluster] ; identify current
cluster
mov cx, ax ; copy current
cluster
mov dx, ax ; copy current
cluster
shr dx, 0x0001 ; divide by two
add cx, dx ; sum for (3/2)
mov bx, 0x0200 ; location of FAT in
memory
add bx, cx ; index into FAT
mov dx, WORD [bx] ; read two bytes from
FAT
test ax, 0x0001
jnz .ODD_CLUSTER
..EVEN_CLUSTER:
and dx, 0000111111111111b ; take low twelve
bits
jmp .DONE
..ODD_CLUSTER:
shr dx, 0x0004 ; take high twelve
bits
..DONE:
mov WORD [cluster], dx ; store new cluster
cmp dx, 0x0FF0 ; test for end of
file
jb LOAD_IMAGE
DONE:
mov si, msgCRLF
call DisplayMessage
push WORD 0x0050
push WORD 0x0000
retf
FAILURE:
mov si, msgFailure
call DisplayMessage
mov ah, 0x00
int 0x16 ; await keypress
int 0x19 ; warm boot computer
loader.bin
----------------------------------------------
org 50h
msg: db 'test'
db 0 ; so you know when to stop
write_screen:
mov ax, 0b800h
mov es, ax
xor di, di
mov si, msg ; point to string
mov ah, 7 ; attribute to use, could be
from a variable
cld
write_loop:
lodsb ; get string character into al
or al, al ; check for 0, end of string
jz write_done
stosw ; write character and
attribute
jmp write_loop
write_done:
------------------------------------------------
PS. If I eventually get out of real mode and into protected mode (when
I understand how it works - I'll look into that later), does the org
100h or similar still apply?
Thanks...
|
|
0
|
|
|
|
Reply
|
Luke
|
2/9/2007 12:32:42 AM
|
|
Luke wrote:
> I am using a sample bootsector I got from the web for the moment. I
> will be using my own eventually. I have included the relevant part of
> the source below.
> I am guessing that I need to use ORG 50h, as that's where the kernel
> is being loaded?
No, segment 50h, offset 0.
> Long story short, I tried org 50h and org 100h, and it displays a few
> garbage characters at seemingly random places on the screen. Should I
> be using ORG something else, or is something else the problem?
Wrong ds, too. In the bootsector, ds was probably 0 or 7C0h (or it
wouldn't have worked). You don't change it when you jump (retf_ to
"loader.bin", so it's still there.
....
> mov ax, 0x0050
> mov es, ax ; destination for
> image
> mov bx, 0x0000 ; destination for
> image
....
> push WORD 0x0050
> push WORD 0x0000
> retf
....
> loader.bin
> ----------------------------------------------
> org 50h
Should be "org 0".
> msg: db 'test'
> db 0 ; so you know when to stop
This gets executed!!! Move it to the end of your code (or jump over it).
push cs
pop ds
Now ds = cs = 50h... es was already 50h from the bootsector. (but you
change it, shortly) I don't think it's any part of your problem, but 50h
is kinda low. You might encounter "extended bios data area" in segment
50h. I'd be tempted to load at 60h:0 - that's where dos loads, I think...
> write_screen:
> mov ax, 0b800h
> mov es, ax
> xor di, di
> mov si, msg ; point to string
> mov ah, 7 ; attribute to use, could be
> from a variable
> cld
>
> write_loop:
> lodsb ; get string character into al
> or al, al ; check for 0, end of string
> jz write_done
> stosw ; write character and
> attribute
> jmp write_loop
>
> write_done:
I think that should fix it...
> ------------------------------------------------
> PS. If I eventually get out of real mode and into protected mode (when
> I understand how it works - I'll look into that later), does the org
> 100h or similar still apply?
Yes. Segment registers are used differently, but they still need to be
set to a "valid" value, and they are still a part of *every* address.
The "base" of the segment is added to the "offset" to form the complete
address. In real mode, the "base" is 16 times the value in the segreg.
In protected mode, the "base" is specified in the descriptor. The
"usual" pmode scheme is "flat memory model" - the "base" of all
descriptors is 0. So the offset is the whole address. The origin "org"
still has to match the address where the code was loaded. Typical "org"
values would be much larger than 100h, but it still applies.
Paging complicates the issue considerably!
Best,
Frank
|
|
0
|
|
|
|
Reply
|
Frank
|
2/9/2007 2:58:38 AM
|
|
Thanks for that, it is working fine now. Now i'm starting to get some
experience behind me :-)
I have included the source below if anyone is interested...
-------------------------------------------------------
;writes a string to video memory
;used in real mode
ORG 0
PUSH CS ;CS = the location in memory where this program is loaded
POP DS ;Move the value of CS into DS
Print:
MOV AX, 0xB800 ;Start location of video memory
MOV ES, AX ;Move video memory location to ES
XOR DI, DI ;Clear Destination Index
MOV SI, msg ;Move our message into memory
MOV AH, 7 ;Set colour attribute (7 = white on black)
CLD ;Clear directional flag. DI increments with each write
(instead of decrements)
Print_Loop:
LODSB ;Loads the first byte of msg
OR AL, AL ;checks for the 0 character
JZ Hang ;If we're up to the 0 character, we are at the end of
the line
STOSW ;Store the character in ES:DI (video memory)
JMP Print_Loop ;Loop to the next character
Hang:
JMP Hang ;End of program
msg: db 'test' ;Message definition
db 0 ;0 character specifying the end of the string
|
|
0
|
|
|
|
Reply
|
Luke
|
2/9/2007 5:26:45 AM
|
|
MOV CX, msglen
REPZ MOVSD
msg: db 't',7,'e',7,'s',7,'t',7 ;ascii, colour attribute
; db ........
fillbytes = ($-msg)-(($-msg)/4)*4)
%if fillbytes >0
times fillbytes DB 0
%endif
msglen = ($-msg)/4
Dirk
|
|
0
|
|
|
|
Reply
|
Dirk
|
2/10/2007 6:12:10 AM
|
|
|
15 Replies
237 Views
(page loaded in 0.263 seconds)
Similiar Articles: Writing to Video Memory - comp.lang.asm.x86Hi, I am trying to write a string to the video memory. I can get individual characters to the screen without a problem, as shown in my code: -----... [bochs][nasm][video memory] - comp.lang.asm.x86> so I may write this: > splash > point 160, 100, 15 > clear_video_memory 0 > draw_screen I wouldn't expect this to work. You write to 9000:xxxx and then clear 9000 ... Keyboard Input - comp.lang.asm.x86I have been trying to figure out how to write a text input driver that is ... PUSH DI ;Save ES:DI > PUSH ES ;ES:DI changes while writing to video memory > MOV ... Lost Memory in RAM card - comp.sys.hp48Writing to Video Memory - comp.lang.asm.x86 Yes, but if you want to copy a memory block to the video RAM like that ... Generator Science with your sound card! ... of very ... write a pixel on VGA - comp.lang.asm.x86[bochs][nasm][video memory] - comp.lang.asm.x86 write a pixel on VGA - comp.lang.asm.x86 [bochs][nasm][video memory] - comp.lang.asm.x86 write a pixel on VGA - comp.lang ... make gdb break on memory location - comp.unix.programmer ...measuring video memory - comp.graphics.api.opengl make gdb break ... debugging - Can I set a breakpoint on 'memory access' in GDB ... watch only breaks on write, rwatch let ... Keyboard Input and Command Line Buffers - comp.lang.asm.x86 ...... have recently been figuring out how to get input from the keyboard and write it ... (you could actually read it back from B800:xxxx, but reading from video memory is ... OpenGL and high-performance image processing. - comp.graphics.api ...What's your opinion about usefulness of the OpenGL extensions as a way write high ... But there is an obstacle: cost of data transfer to video memory and back. Re: Using SSE 128 bit movs From One Memory Location To Another ...Why is the library = function so much faster than anything I can write ... Using [ebp-8] as a memory location - comp.lang.asm.x86 measuring video memory - comp ... stream class video capture minidriver porting to windows 7 X64 ...I have a mission porting original stream class video ... the pointer, I use virtual 64-bit address to write tag. ... (I think data is not flushing to physical memory, so can't ... FAQ -- assembly-language/x86/general/part1 - comp.lang.asm.x86 ...Accessing 4 Gegs of Memory in Real Mode 16. What Is Available at developer ... mode into AL int 10h ;Call VIDEO ;Prepare for writing to the video ... OpenGL video rendering - comp.graphics.api.openglHello, I'm rendering video from a frame grabber ... glMapBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY ... Later, in renderer thread, upload texture from memory ... Switch from protected mode to real mode - comp.lang.asm.x86 ...Directly Reading/Writing to Disk - comp.lang.asm.x86 Switch from protected mode to ... [bochs][nasm][video memory] - comp.lang.asm.x86 > I will be trying to change from real ... HP-UX 11.11 overwriting core file(s) - How to prevent? - comp.sys ...Rather than rename an existing core file before writing another one, or simply ... [bochs][nasm][video memory] - comp.lang.asm.x86 I would expect this to overwrite any bios ... CS, DS, and SS Segments Together? - comp.lang.asm.x86When you are writing a program, you create one or more code segments, and one or ... the lower 640K (which is sometimes useful when programming in DPMI) or the video memory ... Writing directly to video memory? [Archive] - CodeGuru ForumsHello everybody. I'm starting to learn graphics programming in C++. I running in 13h (none of this DirectX crap - I want to understand graphics before I get into that). Writing to video memory from inside protected mode? | KernelTrapHi. Is is possible to write to video memory (B8000h) directly from inside protected mode? How? Thanks, M 7/29/2012 4:52:09 PM
|