2015-02-23 70 views
3

我写一个引导程序如下:创建86引导程序

bits 16 
[org 0x7c00] 
KERN_OFFSET equ 0x1000 
mov [BOOTDISK], dl 
mov dl, 0x0 ;0 is for floppy-disk 
mov ah, 0x2 ;Read function for the interrupt 
mov al, 0x15 ;Read 15 sectors conating kernel 
mov ch, 0x0 ;Use cylinder 0 
mov cl, 0x2 ;Start from the second sector which contains kernel 
mov dh, 0x0 ;Read head 0 
mov bx, KERN_OFFSET 
int 0x13 
jc disk_error 
cmp al, 0x15 
jne disk_error 
jmp KERN_OFFSET:0x0 
jmp $ 

disk_error: 
jmp $ 


BOOTDISK: db 0 

times 510-($-$$) db 0 
dw 0xaa55 

内核是一个简单的C程序,其打印的 “e” 的VGA显示器(看到的QEMU)上:

void main() 
{ 
extern void put_in_mem(); 
char c = 'e'; 
put_in_mem(c, 0xA0); 
} 

我使用此代码在QEMU 16位(实模式),所以我现在用的编译器bcc此代码使用:

bcc -ansi -c -o kernel.o kernel.c 

I有以下问题:
1.当我尝试拆卸本代码,用

objdump -D -b binary -mi386 kernel.o 

我得到这样的(输出的仅初始部分)的输出:

kernel.o:  file format binary 

Disassembly of section .data: 

00000000 <.data>: 
    0: a3 86 01 00 2a   mov %eax,0x2a000186 
    5: 3e 00 00    add %al,%ds:(%eax) 
    8: 00 22     add %ah,(%edx) 
    a: 00 00     add %al,(%eax) 
    c: 00 19     add %bl,(%ecx) 
    e: 00 00     add %al,(%eax) 
    10: 00 55 55    add %dl,0x55(%ebp) 
    13: 55      push %ebp 
    14: 55      push %ebp 
    15: 00 00     add %al,(%eax) 
    17: 00 02     add %al,(%edx) 
    19: 22 00     and (%eax),%al 

该输出似乎不符合我所做的kernel.c文件。例如,我看不到'e'以ASCII 0x65的形式存储在哪里,或者在哪里调用put_in_mem。我拆解代码的方式有问题吗?

  • 为了使内核QEMU我用下面的命令的对象文件:
  •  
    ld86 -o kernel -d kernel.o put_in_mem.o 
    

    这里put_in_mem.o被组装put_in_mem.asm后创建的对象文件其中包含kernel.c中使用的函数put_in_mem()的定义。
    那么对于QEMU软盘映像使用由:

    cat boot.o kernel > floppy_img 
    

    但是,当我尝试看看地址0x10000处(使用GDB),其中内核应该是加载(使用boot.asm程序)后,目前,它不存在。
    这是怎么发生的?
    此外,在ld命令中我们使用了-Ttext选项来指定二进制的加载地址,我们是否应该在这里使用一些类似的选项ld86

    回答

    3

    您的kernel.o是objdump无法理解的目标文件格式,因此它会尝试反汇编其中的所有内容,包括标头和whatnot。尝试反汇编链接输出kernel。另外objdump可能不理解16位代码。如果有可用的话,最好试试objdump86

    至于为什么它不存在:你看错了地方。您正在加载它以抵消0x1000(3个零),但您正在查看0x10000(4个零)。另外请注意,你不设置ES这是不好的做法。也许你打算设置ES0x1000BX0x0000然后你会发现你的内核在0x10000物理地址。

    -Ttext不影响加载,它只是指定代码希望找到自己的位置。

    +0

    较新的GNU objdump变体具有命令行选项“-M i8086”来反汇编16位代码而不是32位代码。 – 2015-02-23 20:48:50

    +0

    -Ttext选项告诉链接器使用我们提供的值偏移本地地址。在加载到RAM中时,不应该给链接器提供这些信息来为机器代码制作合适的地址吗? – sarthak 2015-02-23 20:56:50

    +0

    我刚才说过,它不会影响代码是否加载到哪里,这是首先要解决的问题。 – Jester 2015-02-23 21:49:39