程序集x86 movsb

时间:2014-05-09 04:06:34

标签: video assembly x86 nasm

我正在创建一个两阶段的引导加载程序,第二阶段使用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

1 个答案:

答案 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的倍数,您还必须相应地调整索引寄存器。