2014-05-09 140 views
0

我創建了一個兩級引導加載程序,第二個階段使用了13h(320x200)視頻模式。我決定開始編寫一個簡單的函數來將雙緩衝區複製到視頻內存,問題似乎沒有被複制,代碼:程序集x86 movsb

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個字節的視頻內存的紅色,但沒有happens.Although下面的代碼做這項工作(但我需要存儲器到存儲器)

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

爲什麼第一個代碼段不起作用?

在此先感謝

編輯2:移動直接對和迪:

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

mov di, 0xa000 
mov si, foo 

mov cx, 400 
cld 
rep movsb 
+1

你的意思是使用'mov ax,seg foo'? – Michael

+0

@邁克爾我不明白你的意思! – Mateus

+1

您目前正在執行'mov ax,foo' /'mov ds,ax',這會將'foo'的_offset_放入'ds'中。對我來說,就像你想要'foo'的_segment_一樣。因此建議使用'seg foo'。 – Michael

回答

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的倍數。

+0

謝謝!移動寄存器爲我工作,當我嘗試SEG方法時,我得到了這個錯誤:'二進制輸出格式不支持段基地參考' – Mateus

+0

只是一個疑問。我試着移動地址的foo直接到SI,但它沒有奏效。考慮到foo地址可以用16位表示(例如:0x7E06),它不應該工作嗎? – Mateus

+0

如果清除段寄存器,則直接移至SI應該可以工作。關於賽格不工作,你可能也想嘗試'mov ax,foo >> 4'。 –