【发布时间】:2015-02-24 15:38:52
【问题描述】:
这里我做了一个代码,用于将 ASCII 字符写入 VGA 内存:
.global _put_in_mem
_put_in_mem:
push bp
mov bp, sp
mov cx, [bp + 4]
mov si, [bp + 6]
mov bx, 0xb800
mov ds, bx
mov [si], cx
add bx, 0x1
mov cx, 0x7
mov [si], cx
pop bp
ret
这是通过如下所示的 kernel.c 文件调用的:
void main()
{
extern void put_in_mem();
char c = 'e';
put_in_mem(c, 0xA0);
}
上面的代码是为了在 QEmu 的第二行开头打印“e”,但它没有。我尝试使用 GDB 进行调试,发现命令
mov bx, 0xb800
在GDB中变成了
mov -0x4800,%bx
在这条命令之后的 ebx 中的值为 0x0。
为什么 bx 寄存器中没有加载值?
此外,我认为移动指令使用 ds 寄存器作为它们的段基址,并从 ds 的内容中偏移所有地址。所以根据这个推理,我假设当
mov [si], cx
指令将cx寄存器的内容放在地址0xb8a0处。它是否正确? mov 指令是否也会受到任何其他段寄存器(如 cs、es 等)的影响?
【问题讨论】:
-
这只是一个不稳定的调试器问题,它显示的值好像是一个有符号的数字。不是,0xb800 是一个无符号数。为什么它执行后为 0 是不可猜测的。也许你还没有执行它,也许你不应该在 16 位程序中查看 32 位寄存器。
-
0xb800 == -0x4800在 16 位意义上。 -
好的...但是为什么它没有进入寄存器
-
确保它不是意外的内存引用。由于您的 gdb 输出看起来像 at&t,它通常会显示一个
$用于立即数。因此,您真正拥有的是使用地址0xb800的内存内容加载bx 是可疑的。能查机器码吗? -
“它没有” 那么它在第二行放了什么did,或者放错了地方等等?