so, I want to avoid using int 21h and start working with BIOS level code. I'm trying to write something equivalent to int 21h, function 09h, using int 10h functions 09h, 03h, and 02h, except I want the reading to terminate when it reaches a 00h character, switch to green text when it reaches a 02h character, and switch back to normal when it reaches a 01h character.
Here is my code:

outp proc

		push cx
		push ax
		push bx
		push dx
		
		xor cx,cx
		xor bx,bx
		
nxchr:	add dx,cx
		mov al,[dx]
		cmp al,00h
		jz stwrt
		cmp al,01h
		jnz skp01
		mov attrCUR,attrWHT
skp01:	cmp al,02h
		jnz skp02
		mov attrCUR,attrGRN
skp02:	mov ah,09h
		mov bl,attrCUR
		push cx
		xor cx,cx
		int 10h
		pop cx
		inc cx
		mov ah,03h
		int 10h
		inc dl
		mov ah,02h
		int 10h
		jmp nxchr
		
stwrt:	pop dx
		pop bx
		pop ax
		pop cx
		ret

outp endp

to use this I would set dx to the offset of the beginning of the string andthen call outp.
I'm getting the error that mov al,[dx] is an "illegal indexing mode," and that mov attrCUR,attrWHT and mov attrCUR,attrGRN are illegal memory references, although now that I look at it I can see exactly why. Anyways, how can I move the contents of the memory location in dx into the al register?
Also, I changed mov attrCUR,attrWHT to "mov attrCUR,[offset attrWHT]" and it said constant too large... how do I fix this?

help please...thanks in advance.


----edit----
fixed the mov attrCUR,attrWHT problem... just put the value into bl directly instead of using a memory location intermediate.

Dani AI

Generated

— good diagnosis; was on the right track. In 16-bit x86 the effective-address hardware only accepts BX, BP, SI and DI (and combinations like BX+SI, BP+DI, etc.), so [dx] is not a legal memory operand. That is why copying the offset into SI (or BX/DI/BP as appropriate) fixes the immediate assembler error. Also, memory-to-memory moves are not allowed: move via a register.

A cleaner and faster approach for printing a zero-terminated string with inline control codes is to use the string instructions and write directly to text video memory (color text modes use segment B800h). Keep the current attribute in a register (BL in the example below), switch it on seeing control codes, and use LODSB to fetch bytes from DS:SI and STOSB/STOSW to write to ES:DI. This avoids repeated BIOS calls and gives direct control of attributes.

; DS:DX = offset of zero-terminated string with 01=normal, 02=green
mov si, dx
cld
mov ax, 0B800h
mov es, ax
xor di, di
mov bl, 07h          ; normal attribute (07h = light grey on black)

.next_char:
lodsb                ; AL = [DS:SI++]
cmp al, 0
je .done
cmp al, 01
je .set_normal
cmp al, 02
je .set_green

stosb                ; store character (AL) at ES:DI
mov al, bl
stosb                ; store attribute
jmp .next_char

.set_normal:
mov bl, 07h
jmp .next_char

.set_green:
mov bl, 0Ah          ; light green
jmp .next_char

.done:

Notes and tips: ensure DS points to the data segment that contains the string (load segment if a far pointer is used). For monochrome text modes use B000h instead of B800h. If cursor movement or BIOS-managed behavior is required, BIOS INT 10h services can still be used, but they are slower and may clobber registers — save/restore as needed.

Recommended Answers

All 2 Replies

Firs of all what assembler are you using. The main problem is that you can not move a word to a byte. That is what you are trying to do when you do mov al, dx. Second, if dx is an offset you should be using si ( I am assuming this is a 16 bit program). As for you rsecond question, you can not move a value from one memory address to another. You must move it to a register and then to the second memory location. Hope this helps. I am fairly new to assembly myself so if I have stated something wrong I hope someone will correct me but I am pretty sure this is correct.

yeah that seems right, also, I wasn't moving dx into al, I was trying to move the address contained in dx to al, "mov al,[dx]." I tried using si instead of dx and it seemed to work. Thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.