我正在创建一个两阶段的引导加载程序,第二阶段使用13h(320x200)视频模式。我决定开始编写一个简单的函数来将双缓冲区复制到视频内存中,问题似乎没什么。复制,代码:
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
此代码应该用红色填充视频内存的前400个字节,但没有任何反应。虽然以下代码完成了这项工作(但我需要内存到内存),
mov ax, 0xa000
mov es, ax
mov al, 5
mov cx, 400
cld
rep stosb
为什么第一个代码段不起作用?
提前致谢
编辑2:直接移动到si和di:
xor ax, ax
mov es, ax
mov ds, ax
mov di, 0xa000
mov si, foo
mov cx, 400
cld
rep movsb
答案 0 :(得分:1)
您正在将foo的地址直接移动到段寄存器。您可能已经知道,段寄存器用于保存添加到偏移量的20位地址。在你的情况下,foo的地址类似于0x7E06。当你将它移动到段寄存器并将偏移归零时,你得到地址0x7E06<< 4 + 0 = 0x7E060。
对于这种情况,您可以使用迈克尔在评论中指出的seg:
mov ax, seg foo
mov ds, ax
或者:
mov ax, foo
shr ax, 4
mov ds, ax
请注意,如果您的地址不是16的倍数,您还必须相应地调整索引寄存器。