NASM: 实模式下无效的有效地址
NASM: Invalid effective address in Real Mode
我正在尝试在实模式下绘制到屏幕,因此我正在尝试使用分段访问 0xB8000
我的汇编代码是这样的
[BITS 16]
org 0x7c00
begin:
mov ah, 0x01 ; disable cursor
mov ch, 0x3f
int 0x10
mov ch, 0x0000
mov cs, 0xb800
mov ah, 0x0000
mov [cs:ah], ch ; invalid effective address
end:
jmp end
times 510 - ($-$$) db 0
dw 0xaa55
如何正确使用分段来寻址 0xB8000?
记住cs
是代码段寄存器。 You can't mov
into it。即使可以,您也不会喜欢结果;由于 cs:ip
用于确定从何处获取指令,因此您会发现 CPU 正在执行视频内存的内容。所以你应该使用 ds
或 es
来代替。
接下来,你不能用立即数加载段寄存器;你只能从另一个寄存器或内存中加载它。
最后,您不能使用像 ah
这样的 8 位寄存器作为地址的偏移量部分:偏移量是 16 位。事实上,对于16位8086来说,可以作为有效地址使用的寄存器只有bx, si, di, bp
。参见 。 (bp
寻址使用 ss
段而不是 ds
除非被覆盖,所以在这里可能不应该是您的首选。)
所以您可以改用一些选项:
mov ax, 0xb800
mov ds, ax
mov bx, 0x0000 ; but xor bx, bx is more efficient
mov [bx], ch
mov ax, 0xb800
mov es, ax
mov bx, 0x0000
mov [es:bx], ch
mov ax, 0xb800
mov es, ax
mov [es:0x0000], ch
作为一般原则,在用汇编编写时,您不能只猜测哪些指令采用哪些操作数组合;你必须查一下。您只能使用架构实际实现的那些形式,有时他们的选择并不遵循您可能逻辑上的假设。随着时间的推移,您可能会开始认识到一些模式,但作为初学者,请计划参考您编写的每一行的说明参考。
我正在尝试在实模式下绘制到屏幕,因此我正在尝试使用分段访问 0xB8000
我的汇编代码是这样的
[BITS 16]
org 0x7c00
begin:
mov ah, 0x01 ; disable cursor
mov ch, 0x3f
int 0x10
mov ch, 0x0000
mov cs, 0xb800
mov ah, 0x0000
mov [cs:ah], ch ; invalid effective address
end:
jmp end
times 510 - ($-$$) db 0
dw 0xaa55
如何正确使用分段来寻址 0xB8000?
记住cs
是代码段寄存器。 You can't mov
into it。即使可以,您也不会喜欢结果;由于 cs:ip
用于确定从何处获取指令,因此您会发现 CPU 正在执行视频内存的内容。所以你应该使用 ds
或 es
来代替。
接下来,你不能用立即数加载段寄存器;你只能从另一个寄存器或内存中加载它。
最后,您不能使用像 ah
这样的 8 位寄存器作为地址的偏移量部分:偏移量是 16 位。事实上,对于16位8086来说,可以作为有效地址使用的寄存器只有bx, si, di, bp
。参见 bp
寻址使用 ss
段而不是 ds
除非被覆盖,所以在这里可能不应该是您的首选。)
所以您可以改用一些选项:
mov ax, 0xb800
mov ds, ax
mov bx, 0x0000 ; but xor bx, bx is more efficient
mov [bx], ch
mov ax, 0xb800
mov es, ax
mov bx, 0x0000
mov [es:bx], ch
mov ax, 0xb800
mov es, ax
mov [es:0x0000], ch
作为一般原则,在用汇编编写时,您不能只猜测哪些指令采用哪些操作数组合;你必须查一下。您只能使用架构实际实现的那些形式,有时他们的选择并不遵循您可能逻辑上的假设。随着时间的推移,您可能会开始认识到一些模式,但作为初学者,请计划参考您编写的每一行的说明参考。