Hi , here i'm again, a few dyas ago i was studying a tut of the 8086, and then i took a look to the source code of an example:

ORG 100h ; directive required for a COM program.
MOV AX, 0B800h ; set AX to hexadecimal value of B800h.
MOV DS, AX ; copy value of AX to DS.
MOV CL, 'A' ; set CL to ASCII code of 'A', it is 41h.
MOV CH, 01011111b ; set CH to binary value.
MOV BX, 15Eh ; set BX to 15Eh.
MOV , CX ; copy contents of CX to memory at B800:015E
RET ; returns to operating system.

The tut says it writes directly to video memory, well, but i want to print a string, with color attributes 16 colors, 20x45, 8 pages; and if i use the LEA DX,Msg; INT 21H, doesn't work with color attributes.... :(

MOV AL,String[0]
MOV CX,1
MOV BH,0
MOV BL,0Ah
MOV AH,09h
INT 10h

Im not able to use a bucle, cuz BX is used, AX too, and CX too, and DX cannot be in [], (i don't know why), ok, but i know theres a way to do it, also, how can a get a string length in DOS and for the 8086.


Thanks... HaiKMw
:)
Posted on 2004-03-18 05:55:31 by JaiKMw
DOS code should go into 'the heap', I moved the thread to there.

Thomas
Posted on 2004-03-18 16:24:46 by Thomas
Hi JaiKMw
Here is the way to display a string in 16 bit assembler:-

Firstly you are writing in .com form so all segment registers are initialised to the same value. The segment register you can change is the ES register, changing DS will mess up any fetch instructions. Here is a sample code to display a string with the attributes of your choice.

String DB 'Some text'

push es ;save segment register
mov ax,0b800
mov es,ax
lea si,String ;point at string
mov cx,9 ;number of characters includind spaces
mov ah,14 ;set attribute, in this instance yellow on black
mov di,1938 ;address to be displayed at from offset 0

loop:
lodsb
stosw
dec cx
jne loop
pop es

;the string is now displayed, but if you return immediately to the operating system you won't see it, so put in a wait for keypress as follows:-

xor ah,ah
int 016
ret

It's also a good idea to clear the video buffer before writing to it as follows :-

push es
mov ax,0b800
mov es,ax
mov ax,0020 ;black blank
mov cx,2000 ;number of 16 bit character spaces on 80 * 25 line display
rep stosw
pop es


Another problem you might encounter is the original cursor still flashing on your new display, this can be solved by moving it onto another page as follows :-

mov bh,0
mov dh,26
mov dl,1
mov ah,2
int 010

hope this helps
Posted on 2004-03-19 13:11:49 by Mel
:alright:
Any other problems, just ask.

You might consider using MASM32 to write console applications, there are plenty of examples and help on this board
Posted on 2004-03-19 13:18:48 by Mel
Thanks Thomas for moving this onto the right forum.

Thank you very much Mel ;) , i'm just now reading the String Tut, posted somewhere in this Forum, i have only one question: :confused: , what is for this code:

mov ax,0b800h
mov es,ax


and this:

mov di,1938 ? Thanks JaiKMw
Posted on 2004-03-19 16:04:36 by JaiKMw
I think DI,1938 its for the Coords, but when i write 'mov di,0505' it writes to 5,5 but not the Text!, what is causing this ?? :confused:, but then i write 'mov di,00' and it writes to 0,0 with the text! THanks.. JaiKMw
Posted on 2004-03-19 16:07:35 by JaiKMw
One more Question :D, how do i get the String Length ?
Posted on 2004-03-19 16:10:40 by JaiKMw
The screen layout in 80 * 25 mode consists of 4000 bytes, starting at the top left as 0 and finishing at the bottom right as 3999. Characters are displayed on the even numbers & attributes are the odd numbers so all offsets in DI must be even numbers.
In the example I gave you the length of the string must be manually counted.
The Instructions mov 0b800, mov es,ax is to point at the video buffer so that you can use the string handling instructions of the 8086 i.e. stos etc. es must be restored to its original contents after use hence the push & pop instructions,
hope this helps
Posted on 2004-03-20 02:55:40 by Mel
OK, thanks :), i know we get the string length manually, but how can i get it with a procedure or something ??, i have a code here the moves the string pointer to SI, and then compares it with 0, to search for the end of the null-terminated string, i think this could be useful ??..with colors ??
Posted on 2004-03-20 04:49:18 by JaiKMw
The ascii null terminated string is used in in DOS interrupt 21 procedures, using this method does not allow you to write directly to video memory so you lose control of attributes. You could write your own procedure for getting a string length by putting a control character at the end of strings (maybe zero). Then you can do a compare for this control character and after each compare increment the cx register, when the control character is found the length of the string is contained in cx
Posted on 2004-03-20 06:06:55 by Mel
Hi Mel, Thanks Again, i've managed to make this code: :), what do you think about this ??, i still don't understand the "mov di,1938" part, but don't bother, i'll try to understand that by myself :tongue:...., and :rolleyes:, one more question, how do i assemble this in RadAsm?? do you know how?? Thanks... JaiKMw :alright:

ORG 100h ;...

XOR CX,CX ;Zero Out CX
LEA SI,String ;Load Effective Addres of String into SI.

StrLen:
CMP b.,0 ;Compare the Index Of Letter in SI of the String
;To the End ID Character ($)

JZ _StrLen ;If it has reached the End, then Exit.
;ANd the Length will be in CX.
INC SI ;Else, increment the Index.
INC CX ;And the Temporary Length in CX.
JMP StrLen ;And Compares Again, until the End.
_StrLen:
LEA SI,String ;Load Effective Addres of the String.

PUSH ES ;Backup the Extra Segment.
MOV AX,0B800h ;Video Buffer Address
MOV ES,AX ;Then Move it to ES so we can use The String 80x86
;Functions.
MOV AH,9Ah ;Light Purple Bg, Lime Text.
MOV DI,1938 ;Don't Understand too much.. :(
outstr:
LODSB ;Load String Byte
STOSW ;Store String Word.
DEC CX ;Decrement CX
JNZ outstr ;Jump to outstr if CX is not 0.
;Else...
POP ES ;Restore the Extra Segment.


RET ;Return.

String db 'Hola!, Bienvenidos!...',0

END
Posted on 2004-03-20 07:38:30 by JaiKMw
Looks good to me. The instruction mov di,1938 is pointing di at the position in the video buffer where the text will start displaying from, 1938 is somewhere in the middle of the display. If you loaded di with 160 the string is displayed at the beginning of the second line, 320 is the third line and so on. I can't help you with radasm but I can recommend an assembler called A86, this is readily available if you do a search for it and is the one I used to use for DOS programming
Posted on 2004-03-20 09:14:13 by Mel
Ok, thanks Mel :) , for all your Help :alright:... JaiKMw
Posted on 2004-03-20 21:52:35 by JaiKMw