当 运行 来自引导加载程序时,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
,使用 LODSB
从 buffer
读取。但是,您设置了 DS
段寄存器而不是 ES
。因此,您没有将 'j'
字符存储到您正在读取的相同位置。
解决方法就是设置 ES
和 DS
:
mov ax, 07C0h
mov ds, ax
mov es, ax
注意:您可能还想在使用字符串指令(例如LODSB
、STOSB
)之前明确清除direction flag代码。您可以使用 CLD
指令执行此操作。 BIOS 很可能会在移交给引导扇区之前清除方向标志(这就是为什么它在没有 CLD
的情况下对你有效),但为了绝对确定,你应该自己清除标志。
为了自学汇编语言做了一个小的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
,使用 LODSB
从 buffer
读取。但是,您设置了 DS
段寄存器而不是 ES
。因此,您没有将 'j'
字符存储到您正在读取的相同位置。
解决方法就是设置 ES
和 DS
:
mov ax, 07C0h
mov ds, ax
mov es, ax
注意:您可能还想在使用字符串指令(例如LODSB
、STOSB
)之前明确清除direction flag代码。您可以使用 CLD
指令执行此操作。 BIOS 很可能会在移交给引导扇区之前清除方向标志(这就是为什么它在没有 CLD
的情况下对你有效),但为了绝对确定,你应该自己清除标志。