【发布时间】:2020-01-11 20:13:28
【问题描述】:
我正在重写 xv6 操作系统的引导扇区作为分配,并尝试执行一个无法正确输出到 QEMU 的简单帧。
这是使用 QEMU 模拟器(系统 i386)和适用于 Windows 的 Linux 子系统(使用 Ubuntu 18.04.1 LTS)。将文字传递给%al时,系统确实正确显示了一个字符,并进入了后续的死循环。
.code16
.globl start
start:
cli
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movb $0x0e, %ah
movb hello, %al
movb $0, %bh
movb $7, %bl
int $0x10
stop:
jmp stop
hello:
.string "Hello world."
.org 0x1fe
.word 0xAA55
我希望输出为H,但打印出来的只是S;在大多数其他情况下,它根本不输出任何内容,除非使用文字。
编辑:这是构建后使用objdump 对二进制文件进行的反汇编:
bootsector.img: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <start>:
0: fa cli
1: 31 c0 xor %eax,%eax
3: 8e d8 mov %eax,%ds
5: 8e c0 mov %eax,%es
7: 8e d0 mov %eax,%ss
9: b4 0e mov $0xe,%ah
b: a0 00 00 b7 00 b3 03 movabs 0x10cd03b300b70000,%al
12: cd 10
0000000000000014 <stop>:
14: eb fe jmp 14 <stop>
0000000000000016 <hello>:
16: 48 rex.W
17: 65 6c gs insb (%dx),%es:(%rdi)
19: 6c insb (%dx),%es:(%rdi)
1a: 6f outsl %ds:(%rsi),(%dx)
1b: 20 77 6f and %dh,0x6f(%rdi)
1e: 72 6c jb 8c <hello+0x76>
20: 64 2e 00 00 fs add %al,%cs:(%rax)
...
1fc: 00 00 add %al,(%rax)
1fe: 55 push %rbp
1ff: aa stos %al,%es:(%rdi)
我用来构建和执行代码的步骤:
$ as bootsector.S -o bootsector.img
$ objcopy -O binary bootsector.img
$ qemu-system-i386 bootsector.img -curses
【问题讨论】:
-
您忽略了设置任何段寄存器(它们需要匹配您传递给链接器的任何地址),
movb %7, %bl应该是movb $7, %bl。 -
我已经更正了我重写代码时的错字,但在我测试时它不存在。我已经更新了我的代码来设置段寄存器,但它仍然失败。我想重申,将文字传递给
%al时它确实有效。 -
好点,我想我只是假设那里有一个
int $10? @OP:xorw %ax, %ds不是法律指令,我猜你的意思是mov %ax, %ds?但我们仍然需要看看你是如何链接的。您应该展示所有代码,包括如何组装和创建二进制文件。此外,该程序足够短,您可以包含前几条指令的十六进制转储/反汇编。 -
我在重写代码时犯了很多错误,对不起。我完全更正了帖子中的代码,并包含了反汇编。
-
@user3658679:你是如何创建
bootsector.img的?发布命令行步骤,否则请查看例如stackoverflow.com/q/32508919/786653
标签: assembly x86 bootloader gnu-assembler xv6