标签: real-mode

引导加载程序-加载第二阶段-qemu正常运行,真实机器无法运行

作为学习练习,我为x86 bios系统编写了一个16位的引导程序。它在QEMU上似乎运行良好。我将其添加到用于旧式amd-turion计算机(x86_64)的驱动器上,当我尝试引导该计算机时,它将进入BIOS屏幕,然后黑屏上的光标闪烁。

我的问题是,QEMU的x86仿真器和绝对使用BIOS而不是UEFI的真实x86(64位)计算机之间可能有什么区别?我是否需要针对实际计算机而不是QEMU编写代码?是我将信息复制到驱动器的方式吗?计算机是否采用了某些硬件级别的安全性规定?

我知道它在VirtualBox上也不起作用。

看来加载第二阶段是有问题的(通过在真实硬件上成功地打印第一阶段的字符)

我的第一阶段引导程序使用以下文件中的代码:

stage_one.asm

[bits 16]
[org 0x7c00]
LOAD_ADDR: equ 0x9000   ; This is where I'm loading the 2nd stage in RAM.
start:
    xor ax, ax          ; nullify ax so we can set 
    mov ds, ax          ; ds to 0
    mov sp, bp          ; relatively out of the way
    mov bp, 0x8000      ; set up the stack
    call disk_load      ; load the new instructions
                        ; at …
Run Code Online (Sandbox Code Playgroud)

qemu real-mode nasm bare-metal bootloader

5
推荐指数
1
解决办法
560
查看次数

放置堆栈并加载内核的位置

我是操作系统开发的新手,我很好奇我在开发自己的bootloader时遇到的问题.我的操作系统将以汇编语言编写,并将以16位实模式运行.

我知道堆栈是什么,我的印象是它向下扩展到内存中.如果我错了,请纠正我.我知道如何从软盘中将基本内核加载到内存中,我不相信这是问题所在.

我遇到的问题是我不确定在哪里放置堆栈并将内核加载到内存中.我试过像这样创建我的堆栈,我遇到了问题:

mov ax, 0x0000
mov ss, ax
mov sp, 0xFFFF
Run Code Online (Sandbox Code Playgroud)

我正在加载我的内核0x1000:0x0000.当我推送并稍后在我的函数中弹出易失性寄存器时print,我的内核只是第二次挂起call print.这是我的print功能:

print:
    push ax
    push bx
    push cx

    mov al, [si]
    cmp al, 0
    je p_Done

    cmp al, 9
    je p_Tab

    mov ah, 0xE
    int 0x10

    cmp al, 10
    je p_NewLine
   p_Return:
    inc si
    jmp print
  p_Tab:
    xor cx, cx
   p_Tab_Repeat:
    cmp cx, 8
    je p_Return
    mov ah, 0xE
    mov al, " " …
Run Code Online (Sandbox Code Playgroud)

assembly stack real-mode osdev x86-16

5
推荐指数
1
解决办法
230
查看次数

无效的基/索引表达式

尝试使用基索引表达式在 16 位实模式下操作内存会导致编译错误:

movw    $0xd000, -2(%sp)
movw    $0, -4(%sp)
movw    $1, -6(%sp)
Run Code Online (Sandbox Code Playgroud)

编译为

gcc -c -Wa,--32 $(DIR_BS_SRC)/mbr.S -o $(DIR_BS_SRC)/mbr.o
ld -nostdlib --oformat binary --Ttext 0x7c00 $(DIR_BS_SRC)/mbr.o -o $(DIR_B$
Run Code Online (Sandbox Code Playgroud)

产生以下错误:

bootsector/src/mbr.S:20: Error: `-2(%sp)' is not a valid base/index expression
bootsector/src/mbr.S:21: Error: `-4(%sp)' is not a valid base/index expression
bootsector/src/mbr.S:22: Error: `-6(%sp)' is not a valid base/index expression
Run Code Online (Sandbox Code Playgroud)

我认为这是有效的语法,即使在 16 位实模式下也是如此?

x86 assembly real-mode gnu-assembler

4
推荐指数
1
解决办法
5677
查看次数

引导加载程序后如何从实模式切换到保护模式?

我刚刚为我的操作系统完成了一个非常简单的引导加载程序,现在我正在尝试切换到保护模式并跳转到内核.

内核存在于第二个扇区(在引导加载程序之后)并且打开.

任何人都可以帮我解决我的代码吗?我添加了评论,以显示我的困惑在哪里.

谢谢.

BITS 16 

global start
start:
    ; initialize bootloader and stack
    mov     ax, 0x07C0
    add     ax, 288
    mov     ss, ax
    mov     sp, 4096
    mov     ax, 0x07C0
    mov     ds, ax

    call    kernel_load
    hlt

kernel_load:
    mov     si, k_load
    call    print

    mov     ax, 0x7C0
    mov     ds, ax
    mov     ah, 2
    mov     al, 1
    push    word 0x1000
    pop     es
    xor     bx, bx
    mov     cx, 2
    mov     dx, 0
    int     0x13

    jnc     .kjump
    mov     si, k_fail
    call    print
    ret

.kjump:
    mov     si, …
Run Code Online (Sandbox Code Playgroud)

x86 operating-system real-mode protected-mode bootloader

4
推荐指数
1
解决办法
5533
查看次数

在不使用C库的情况下在0xb8000处显示文本视频内存

我一直在用C编写内核.我一直在使用GCC交叉编译器,在Windows系统上编写并以16位实模式为目标.我没有可用于编写内核的C库.我已经开始使用一些代码来假设将字符直接打印到屏幕上.这是一个函数来自kernel.c:

int main()
{
  char *src = (char *)0xB8000000L;
  *src = 'M';
  src += 2;
  *src = 'D';
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用GCC编译了我的代码,并使用参数-m16生成将在实模式下运行的代码.我使用这些命令来生成我的kernel.bin:

gcc -ffreestanding -c -m16 kernel.c -o kernel.o
ld -Ttext 0x10000 -o kernel.pe kernel.o
objcopy -O binary kernel.pe kernel.bin
Run Code Online (Sandbox Code Playgroud)

Stack Overflow用户Michael Petch解决了我的链接器问题,但评论代码本身是不正确的.他发表了这样的评论:

除链接器问题外,您是否尝试将旧的TurboC/MSVC 16位代码转换为GCC?我发现(char*)0xB8000000L可疑.如果它是一个真正的16位C编译器,它可能是好的,如果它是(char far*)0xB8000000L.GCC不是一个真正的16位C编译器,并没有旧式远指针的概念.所以,即使你得到这个代码进行编译,这可能不会做你认为它做的,我假设从-m16选项与GCC你正在尝试创建一个实模式16位内核(而不是保护模式一个) )?

我一直在尝试printf在C中为我自己的操作系统实现自己的类似功能.我上面提供的代码只是我理解的一小部分.我在程序集中创建了一个bootloader(8086).

迈克尔是对的吗?如果是这样,我该如何解决这个问题并直接写入视频内存0xb8000

assembly kernel real-mode osdev x86-16

4
推荐指数
1
解决办法
1349
查看次数

如果我尝试将其指向标签,为什么x86-assembly(r)中的寄存器会自动移入?

我想写一个bootloader,它只是打印"Hello World!" 在屏幕上,我不知道为什么我的字节混淆了.我正在尝试用AT&T语法编写它(请不要推荐英特尔语法)并尝试将本教程中的代码转换为AT&T语法.

现在这里是我的bootloader的相当短的代码:

start:
.code16         #real mode
.text
.org 0x0
.globl _main
_main:
    movw hello, %si
    movb $0x0e, %ah

loophere:
    lodsb
    or %al, %al     #is al==0 ?
    jz halt         #if previous instruction sets zero flag jump to halt
    int $0x10       #run bios interrupt 0x10 (ah is set to 0x0e so a character is displayed)
    jmp loophere


halt:
    cli
    hlt


hello:  .ascii "Hello world!\0"


filloop:    
    .fill (510-(.-_main)),1,0   #I hope this works. Fill bootloader with 0's until byte 510 …
Run Code Online (Sandbox Code Playgroud)

x86 assembly real-mode gnu-assembler bootloader

4
推荐指数
1
解决办法
201
查看次数

如何在MOV和LEA指令后确定AX中的结果

我想在下面的问题中了解AX寄存器的内容,我不明白我怎么知道示例中的[5000h]或[DI]是什么.

寄存器和存储器的状态定义为:

CS=3000 [53000]=BBBB [33000]=6666 [13000]=1111
DS=1000 [54000]=CCCC [34000]=7777 [14000]=2222
SS=5000 [55000]=DDDD [35000]=8888 [15000]=3333
DI=7000 [56000]=EEEE [36000]=9999 [16000]=4444
BP=4000 [57000]=FFFF [37000]=AAAA [17000]=5555
Run Code Online (Sandbox Code Playgroud)

AX中的每个指令的值是多少

  • MOV AX, [DI]
  • MOV AX, [5000h]
  • MOV AX, [BP+2000h]
  • LEA AX, [BP+1000h]

x86 assembly real-mode x86-16

4
推荐指数
1
解决办法
135
查看次数

为什么即使 DPMI 主机处于活动状态,INT 31H 也没有正确设置?

我在 MS-DOS 中进行了大量的汇编编程试验。我读过 Windows 3.1 充当 DOS 程序的 DPMI 主机,并且 DPMI 使用中断 31h 进行函数调用。

所以让我们试一试。我在 Windows 3.1 中打开 DOS 提示符...

C:\WINDOWS>debug
-a100
23A4:0100 mov ax,0400
23A4:0103 int 31
23A4:0105
-r
AX=0000  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=23A4  ES=23A4  SS=23A4  CS=23A4  IP=0100   NV UP EI PL NZ NA PO NC
23A4:0100 B80004        MOV     AX,0400
-p

AX=0400  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=23A4  ES=23A4  SS=23A4  CS=23A4  IP=0103   NV UP EI PL NZ NA PO NC
23A4:0103 CD31          INT …
Run Code Online (Sandbox Code Playgroud)

x86 assembly dos real-mode windows-3.1

4
推荐指数
1
解决办法
78
查看次数

如何实现 Int 16h 以使用键盘浏览我的程序?

我的目标是使用 Int 16 指令能够使用箭头键在程序中上下移动,直到我的用户决定按退出键。我是否在循环中使用以下代码读取多个按键并在末尾添加终止条件,或者是否缺少某些内容?

Mov ah,00
int 16
Run Code Online (Sandbox Code Playgroud)

assembly real-mode bios x86-16

3
推荐指数
1
解决办法
8204
查看次数

将值写入BX寄存器是否会影响ES寄存器?

[org 0x7c00]
    mov bp, 0x8000 ; set the stack safely away from us
    mov sp, bp

    mov bx, 0x9000 ; es:bx = 0x0000:0x9000 = 0x09000
Run Code Online (Sandbox Code Playgroud)

正如你可以在注释中看到它说:es:bx = 0x0000:0x9000 = 0x09000。寄存器ESBX之间有什么关系?该代码仅设置寄存器BX,但注释显示寄存器ES也被设置?

x86 assembly real-mode nasm bootloader

3
推荐指数
1
解决办法
111
查看次数