Вопрос

I'm creating a two stages bootloader,the second stage uses 13h(320x200) video mode.I decided to start writing a simple function to copy a double buffer to the video memory,the problem is nothing seems to be copied,the code:

org 0x7E00
xor ax, ax
mov ds, ax

jmp begin

foo: times 400 db 5

govideo:
mov ah, 0
mov al, 13h
int 10h
ret

begin:
call govideo

mov ax, 0xa000 ; video memory address
mov es, ax     ; es,address to receive
mov di, 0x0    ; no offset
mov ax, foo    ; foo,the test double buffer,all bytes initialized with 5(red color)
mov ds, ax     ; ds,address to copy 
mov si, 0x0    ; no offset
mov cx, 400    ; all foo 400 bytes
cld            ; clear direction flag,so es and ds get incremented
rep movsb      ; copy all 400 bytes

terminate:
times 510-($-$$) db 0

This code should fill the first 400 bytes of the video memory with the red color,but nothing happens.Although the following code does the job(but i need memory to memory),

mov ax, 0xa000
mov es, ax
mov al, 5
mov cx, 400
cld
rep stosb

Why the first snippet doesn't work?

Thanks in advance

Edit 2:Moving directly to si and di:

xor ax, ax
mov es, ax
mov ds, ax

mov di, 0xa000
mov si, foo

mov cx, 400
cld
rep movsb
Это было полезно?

Решение

You are moving address of foo directly to segment register. As you probably already know, segment registers are used to hold 20-bit address that is added to the offset. In your case address of foo is something like 0x7E06. When you move this to segment register and zero out the offset, you get address 0x7E06 << 4 + 0 = 0x7E060.

For this case you can use seg as Michael pointed out in the comments:

mov ax, seg foo
mov ds, ax

Or alternatively:

mov ax, foo
shr ax, 4
mov ds, ax

Note that you also have to adjust index register accordingly if your address is not multiple of 16.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top