在保护模式下将字符打印到屏幕 ASM

2024-02-22

我正在尝试进入保护模式,然后打印出“Hi”

但相反,它只是从我的 BIOS 中断调用中打印“正在加载操作系统”(在进入 pmode 之前发生),而没有其他内容。

My 引导加载程序.asm

%DEFINE KERNEL_LOAD_OFFSET 0x1000

org 0x7c00

bits 16

xor ax, ax
mov ds, ax

start: jmp main

Print:
 .print:
  lodsb
  or al, al
  je .done

  mov ah, 0x0E
  int 0x10

  .repeat:
   jmp .print

 .done:
  ret

ResetFloppy:
 mov ah, 0x0

 int 0x13
 jc ErrorFloppy
 .done:
  ret

ReadFloppy:

 mov ah, 0x02
 int 0x13

 jc ErrorFloppy

 .done:
  ret

ErrorFloppy:

 mov si, msgErrorFloppy
 call Print

 jmp hang


main: 
 .print:

  mov si, msg
  call Print

 .loadFile:
  mov al, 0xF
  mov ch, 0x0
  mov cl, 0x02
  mov dh, 0x0
  mov dl, 0x0
  mov bx, KERNEL_LOAD_OFFSET

  call ResetFloppy
  call ReadFloppy


 .loadGDT:
   lgdt [gdtr]
 .pM_start:
  cli
  pusha

  mov eax, cr0
  or al, 1
  mov cr0, eax

  popa

  jmp 0x08:ljmp_pM


 bits 32
 ljmp_pM: 
  mov ax, 0x10
  mov ds, ax
  mov ss, ax
  mov fs, ax
  mov es, ax
  mov gs, ax

  jmp KERNEL_LOAD_OFFSET

hang:
 jmp $

gdt:
NULL_DESC:
    dd 0            ; null descriptor
    dd 0

CODE_DESC:
    dw 0xFFFF       ; limit low
    dw 0            ; base low
    db 0            ; base middle
    db 10011010b    ; access
    db 11001111b    ; granularity
    db 0            ; base high

DATA_DESC:
    dw 0xFFFF       ; data descriptor
    dw 0            ; limit low
    db 0            ; base low
    db 10010010b    ; access
    db 11001111b    ; granularity
    db 0            ; base high

gdtr:
    Limit dw 24         ; length of GDT
    Base dd NULL_DESC   ; base of GDT

msg db "Loading OS", 13, 10, 0
msgErrorFloppy db "There was an error with the floppy", 13, 10, 0

FILL:
 times 510-($-$$) db 0

BOOTSECTOR:
 dw 0xAA55

内核asm

bits 32

mov dword [0xB8000], 0x07690748

jmp $

And 编译.bat

nasm -f bin Dev/BootLoader.asm -o Bin/BootLoader.bin
nasm -f bin Dev/Kernel.asm -o Bin/Kernel.bin

dd if=Bin/BootLoader.bin of=Image/Image.img seek=0
dd if=Bin/Kernel.bin of=Image/Image.img seek=1 conv=notrunc

pause

我用博克斯。我得到的只是这样:http://prntscr.com/d24wmm http://prntscr.com/d24wmm


在 32 位保护模式下,您无法使用 BIOS,因为它是用 16 位实模式代码编写的。因此,您必须像这样访问视频内存:

    mov ebx,0xb8000    ; The video address
    mov al,'!'         ; The character to be print
    mov ah,0x0F        ; The color: white(F) on black(0)
    mov [ebx],ax        ; Put the character into the video memory

然后你可能会看到一个!在屏幕的开头。如果你只想在光标位置打印,你可以这样获取光标偏移量:

    mov dx,0x3D4       ; Tell the control I/O port to get the lower byte of
    mov al,0x0F        ; the cursor offset
    out dx,al
    mov dx,0x3D5       ; Switch to data I/O port
    in  al,dx          ; Get the cursor offset's lower byte

    mov dx,0x3D5       ; Tell the control I/O port to get the higher byte of
    mov al,0x0E        ; the cursor offset
    out dx,al
    mov dx,0x3D5       ; Switch to data I/O port
    in  al,dx          ; Get the higher byte

    imul ax,2           ; Because a character in video memory costs 2 bytes
                       ; (i.e character and attribute), we need to twice the cursor offset

在 32 位保护模式下,为了提高代码的效率,您可以使用一些高级语言,例如C创建函数。这确实增加了代码的可读性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在保护模式下将字符打印到屏幕 ASM 的相关文章

  • 为什么 SSE 对齐读取 + 随机播放在某些 CPU 上比未对齐读取慢,而在其他 CPU 上则不然?

    在尝试优化有限差分代码所需的未对齐读取时 我更改了未对齐的负载 如下所示 m128 pm1 mm loadu ps H k 1 进入这个对齐的读取 随机播放代码 m128 p0 mm load ps H k m128 pm4 mm load
  • 这段汇编语言代码是什么意思?

    我是一名学生 刚刚开始学习汇编语言 为了更好地理解它 我只是用 C 写了一个简短的代码并将其转换为汇编语言 奇怪的是我有点听不懂 代码是 include
  • 在 x86 程序集中将整数打印到控制台

    当我在 16 位汇编中添加两个值时 将结果打印到控制台的最佳方法是什么 目前我有这个代码 CODE START mov ax 1 put 1 into ax add ax 2 add 2 to ax current value mov ah
  • 为什么 Solaris 汇编器生成的机器代码与 GNU 汇编器在这里不同?

    我为 amd64 编写了这个小汇编文件 对于这个问题来说 代码的作用并不重要 globl fib fib mov edi ecx xor eax eax jrcxz 1f lea 1 rax ebx 0 add rbx rax xchg r
  • 奇怪的 MSC 8.0 错误:“ESP 的值未在函数调用中正确保存...”

    我们最近尝试将一些 Visual Studio 项目分解为库 并且在测试项目中一切似乎都编译和构建得很好 其中一个库项目作为依赖项 然而 尝试运行该应用程序给我们带来了以下令人讨厌的运行时错误消息 运行时检查失败 0 ESP 的值未在函数调
  • 在linux x86平台上学习ARM所需的工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个 x86 linux 机器 在阅读一些关于 ARM 的各种信息时 我很好奇 现在我想花一些时间学
  • 近调用/跳转表并不总是在引导加载程序中工作

    一般问题 我一直在开发一个简单的引导加载程序 并在某些环境中偶然发现了一个问题 在这些环境中 此类指令不起作用 mov si call tbl SI Call table pointer call call tbl Call print c
  • 减法进位标志

    我正在使用 MASM32 有了这个代码 mov eax 5 sub eax 10 CF 状态标志将被设置 但使用我的铅笔和纸 我实际上看到 MSB 没有任何进位 是的 我知道从较少的数字中减去大的数字集CF 但我想知道为什么 因为使用这段代
  • 为什么 RISC-V S-B 和 U-J 指令类型以这种方式编码?

    我正在读一本书 计算机组织与设计RISC V版 我遇到了 S B 和 U J 指令类型的编码 我上面提到的那些类型有奇怪的编码立即字段 S B 类型将直接字段分为两部分 这是有道理的 因为所有指令编码都必须相似 但我无法理解为什么立即字段以
  • 为什么x86分页没有特权环的概念?

    早在 1982 年 当 Intel 发布 80286 时 他们在分段方案中添加了 4 个特权级别 环 0 3 由全局描述符表 GDT 和局部描述符表 LDT 中的 2 位指定 在 80386 处理器中 Intel 添加了分页功能 但令人惊讶
  • 在 x86-64 CPU 上通过交叉修改代码重现意外行为

    Question 对于可能在 x86 或 x86 x64 系统上触发意外行为的交叉修改代码有哪些想法 在这些系统中 交叉修改代码中的所有操作均已正确完成 但在执行处理器之前执行序列化指令除外修改代码 如下所述 我有一个 Core 2 Duo
  • 汇编8086监听键盘中断

    我有与此完全相同的问题 边画边听键盘 https stackoverflow com questions 13970325 8086 listen to keyboard while drawing 但第一个答案 接受的答案 只听键盘一次
  • 为什么 GCC 不将 a*a*a*a*a*a 优化为 (a*a*a)*(a*a*a)?

    我正在对科学应用程序进行一些数值优化 我注意到的一件事是 GCC 会优化调用pow a 2 通过将其编译成a a 但是调用pow a 6 没有优化 实际会调用库函数pow 这大大降低了性能 相比之下 英特尔 C 编译器 http en wi
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • ARMv8 A64 汇编中立即值的范围

    我的理解是 ARMv8 A64 汇编中的立即参数可以是 12 位长 如果是这样的话 为什么这行汇编代码是 AND X12 X10 0xFEF 产生此错误 使用 gcc 编译时 Error immediate out of range at
  • 如何在 Debian 上编译 DOS 程序?

    在我的汇编语言课程中 我们使用 DPMI 编写 DOS 程序 不幸的是 我无法一直使用 32 位 Windows 机器 我在我使用的几乎每台计算机上都安装了 Debian 虚拟机 我已经安装了 DOSBox 和 DOSEMU 有什么办法可以
  • 为什么如果内存组织为字,则程序计数器加 1;如果内存组织为字节,则程序计数器加 2?

    如果在计算机中一条指令是 16 位 并且如果存储器被组织为 16 位字 则通过在当前指令的地址中加 1 来计算下一条指令的地址 如果内存是按字节组织的 可以单独寻址 那么我们需要在当前指令地址上加二 得到顺序执行的下一条指令的地址 为什么会
  • Linux内核页表更新

    在linux x86 中分页 每个进程都有它自己的页面目录 页表遍历从 CR3 指向的页目录开始 每个进程共享内核页目录内容 假设三个句子是正确的 假设某个进程进入内核 模式并更新他的内核页目录内容 地址映射 访问 权利等 问题 由于内核地
  • CPU寄存器和多任务处理

    我目前正在学习汇编 我很困惑 CPU 寄存器如何与多任务一起工作 所以在多任务系统中 CPU可以随时暂停某个程序的执行并运行另一个程序 那么在这一步中寄存器值是如何保存的呢 寄存器是压入堆栈还是以其他方式 CPU 寄存器如何与多任务一起工作
  • 如何将 x86 GCC 风格的 C 内联汇编转换为 Rust 内联汇编?

    我在 C 中有以下内联汇编 unsigned long long result asm volatile byte 15 byte 49 shlq 32 rdx orq rdx rax a result rdx return result

随机推荐