当 运行 来自引导加载程序时,STOSB 指令不存储字节

STOSB instruction not storing byte when run from a bootloader

为了自学汇编语言做了一个小的bootloader 后,我发现stosb 指令似乎不起作用。我将问题压缩为一个最小的例子:

BITS 16

start:
mov ax, 07C0h       
add ax, 288     
mov ss, ax
mov sp, 4096

mov ax, 07C0h       
mov ds, ax ;setting up stack

mov al, 'j'
mov di, buffer
stosb

mov si, buffer
jmp loops

loops:
mov ah, 0Eh
lodsb
cmp al, 0
je done
int 10h
jmp loops

done:
hlt

buffer times 64 db 0

times 510-($-$$) db 0   ; Pad remainder of boot sector with 0s
dw 0xAA55

当此引导加载程序 运行 时,它应该将字母 j 存储到缓冲区中,然后将该缓冲区打印到显示器上。输出应该是:

j

当运行时,它似乎没有打印任何东西。有什么问题,我该如何解决?

Michael Petch、Weather Vane、Jim Mischel 和 GJ 在评论中给出了解决方案。详细说明:

STOSB指令隐式存储数据到[ES:DI],而LODSB指令隐式从[DS:SI]加载数据。您使用 STOSB 写入 buffer,使用 LODSBbuffer 读取。但是,您设置了 DS 段寄存器而不是 ES。因此,您没有将 'j' 字符存储到您正在读取的相同位置。

解决方法就是设置 ESDS:

mov ax, 07C0h       
mov ds, ax
mov es, ax

注意:您可能还想在使用字符串指令(例如LODSBSTOSB)之前明确清除direction flag代码。您可以使用 CLD 指令执行此操作。 BIOS 很可能会在移交给引导扇区之前清除方向标志(这就是为什么它在没有 CLD 的情况下对你有效),但为了绝对确定,你应该自己清除标志。