x86中内存分段的混乱

时间:2015-02-24 15:38:52

标签: c assembly x86

这里我制作了一个代码,用于将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);
}

以上代码旨在打印" e"在QEmu的第二行开头,但事实并非如此。我尝试使用GDB进行调试,发现命令

mov bx, 0xb800
GDB中的

已成为

mov    -0x4800,%bx

此命令后ebx中的值为0x0 为什么没有在bx寄存器中加载该值?

此外,我认为移动指令使用ds寄存器作为其段基,并从ds的内容中偏移所有地址。所以根据这个推理,我假设当

mov [si], cx

指令将cx寄存器的内容放在地址0xb8a0。它是否正确? mov指令是否也会受到任何其他segement寄存器(如cs,es等)的影响?

2 个答案:

答案 0 :(得分:4)

例程_put_in_mem存在一些问题,它不保留必须根据16位x86调用约定保留的寄存器DS和SI,参见this document的第6节,它没有' t正确存储字符和属性字节。

.global _put_in_mem
_put_in_mem:
push bp
mov bp, sp
mov cx, [bp + 4]
mov si, [bp + 6]   # si must be preserved across function calls
mov bx, 0xb800
mov ds, bx         # ds must be preserved across function calls
mov [si], cx
add bx, 0x1
mov cx, 0x7        # low byte 0x7, upper byte = character = 0x00
mov [si], cx       # si has not changed... overwriting with 0x0007
pop bp
ret

这是修复它的一种方法:

.global _put_in_mem
_put_in_mem:
push bp
mov bp, sp
mov cx, [bp + 4]   # cx = xxcc, where cc is ASCII character
mov ch, 0x7        # attribute byte: light-grey on black
mov bx, [bp + 6]   # bx = offset into VGA video buffer
mov ax, 0xb800     # VGA video buffer base at 0xb800 x 16
mov es, ax         # use ES segment register instead of DS
mov es:[bx], cx    # store ASCII at es:[bx], attribute at es:[bx+1]
pop bp
ret

VGA attribute字节在文本模式下跟随字符字节。属性0x7表示在黑色背景上显示为浅灰色...请参阅http://wiki.osdev.org/Printing_To_Screenhttp://en.wikipedia.org/wiki/VGA-compatible_text_mode

答案 1 :(得分:3)

确保它不是意外的内存引用。由于你的gdb输出看起来像是& t,它通常会显示$ for immediates。因此,您怀疑您真正拥有的是使用地址0xb800处的内存内容加载bx。你能查一下机器代码吗?

  

机器代码为0xb8001e8b

确实,这是用于从内存加载的机器代码。查看as86 manual,您可以看到:

#      Prefix for immediate operands.
       mov ax,#1234
       Immediate value, ax becomes 1234.

因此,您应该在您的immediates前面添加#符号。请注意,这适用于所有中级人员。

虽然这可以解决您提出的问题,但请参阅@ amdn&#39答案,了解您遇到的其他问题。