【问题标题】:why cant i get disk_read_error to print为什么我不能打印磁盘读取错误
【发布时间】:2021-09-26 03:44:59
【问题描述】:
[org 0x7c00]                  ; declares the origin to 0x7c00
mov bp, 0x7c00                ; move the memory adress 0x7c00 to the base pointer, CS:IP always points to physical address 0x07C00.
mov sp, bp                    ; move the base pointer to the stack pointer

Hello_World:                  ; declares the label of the hello World position
db 'Hello World!',0           ; declares the string Hello World!
mov bx, Hello_World           ; move Hello_World labels position to bx[16 bit]
call printstring              ; calls the printsctring function
printstring:                  ; declares position of printstring function
     mov ah, 0x0e              
     .loop:                    ; declares position of loop
     cmp [bx], byte 0         ; compares a size of 0 bytes to bx
     je .exit                 ; if the result is equal jump to exit
               mov al, [bx]   ; declares move value at bx to al.
               int 0x10       ; declares print
               inc bx         ; increment the bx as a for loop
               jmp .loop      ; jump to the for loop
.exit:                        ; labels position of exit
ret                           ; returns from read_disk to its call

mov [boot_disk], dl           ; moves dl contents to boot disk error
boot_disk:                    ; declares boot_disk position
          db 0                ; defines a byte of 0
                              ; boot disk should now store the disk number inside the defined byte
program_space equ 0x7e00      ; program space variable equates to 0x7e00. 
                              ; 0x7e00 is 512 bytes after 0x7c00 in memory
call read_disk                ; calls read_disk function position





read_disk:                    ; declares read_disk position

mov bx, program_space         ; moves the program space to bx
mov al, 5                     ; reads 4 sectors aka 2000 bytes, or 2 kilobytes
mov dl, [boot_disk]           ; moves the value of boot disk into dl
mov ch, 0x00                  ; moves cyclinder 0 of hard drive into ch
mov dh, 0x00                  ; moves cyclinder 0 of hard drive into dh
mov cl, 0x02                  ; Moves 2 cylinders to cl

int 0x13                      ; interrupt commands the bios to read the disk
jc disk_read_failed           ; jumps conditionaly to disk read failed
ret                           ; returns to position of call printstring

disk_read_error:              ; declares disk_read_error position
db 'disk read failed',0         ; defines byte as disk read failed
disk_read_failed:             ; declares the label of disk_read_failed position
mov bx, disk_read_error       ; moves disk_read_error to bx
call printstring              ; calls the printing of the bx within a for loop.
jmp $

jmp $                         ; declares infinite loop
times 510-($-$$) db 0         ; declares bootloader size as 510 bites
dw 0xaa55                     ; declares this as a bootloader and uses 2 bites
                              ; total bites = 512 bites = 2 bites + 510 bites

【问题讨论】:

  • 快速浏览一下,发现您将“Hello World”数据放在代码旁边。处理器执行“mov sp,bp”指令后,会将“Hello World”数据字节解释为指令。您必须将数据放在执行流之外的某个位置。

标签: assembly nasm x86-16 bootloader


【解决方案1】:

大量混合了可执行代码和数据!然后发生的事情是 CPU 尽最大努力将您的数据解释为代码,当然不是这样,因此您可以看到发生的最奇怪的事情……如果幸运的话,其中最好的是完全冻结.

消息和变量以及它们的标签都属于可执行代码的下方。您直接放置在数据上方的子例程


mov bp, 0x7C00
mov sp, bp

在这个简单的代码中你不需要设置堆栈,你还应该设置SS 是正确的。

mov bx, Hello_World
call printstring

printstring 子例程中使用的 BIOS.Teletype 函数需要 BH 中的 DisplayPage 参数和 BL 中的(图形)颜色。你永远不应该使用BX 来指向消息!为此,请使用 SIDI

call printstring              ; calls the printsctring function
printstring:                  ; declares position of printstring function

这里发生的错误是,在call 返回后,代码将错误地通过 printstring 子例程,并在完成后执行ret 基于不存在的返回地址!

mov al, 5           ; reads 4 sectors aka 2000 bytes, or 2 kilobytes

使用 5 值,您将读取 5 个 512 字节的扇区,总计 2560 字节。使用 4,您将读取 2KB 或 2048 字节。


您的代码缺少的是设置DSES 段寄存器。您需要一个正确的DS 来处理消息和变量,并且您需要一个正确的ES,因为BIOS.ReadSectors 函数需要它。顺便提一下AH中的函数号。

这是代码的清理版本:

program_space equ 0x7E00

[org 0x7C00]

  xor  ax, ax
  mov  ds, ax
  mov  es, ax

  mov  [boot_disk], dl

  mov  di, Hello_World
  call printstring

  call read_disk

  jmp $

; ---------------------------- SUBROUTINES ---

printstring:
  mov  bx, 7                  ; BH=0 DisplayPage, BL=7 Color White
.loop:
  mov  al, [di]
  cmp  al, 0
  je   .exit
  mov  ah, 0x0E               ; BIOS.Teletype
  int  0x10
  inc  di
  jmp  .loop
.exit:
  ret

; ----------------------------

read_disk:
  mov  dh, 0                  ; DH=0 Head
  mov  dl, [boot_disk]
  mov  cx, 0x0002             ; CH=0 Cylinder, CL=2 SectorNumber
  mov  bx, program_space      ; ES:BX
  mov  ax, 0x0204             ; AH=2 FunctionNumber, AL=4 NumberOfSectors
  int  0x13
  jc   disk_read_failed
  ret
disk_read_failed:
  mov  di, disk_read_error
  call printstring
  jmp  $

; ---------------------------- DATA ---

Hello_World:      db 'Hello World!', 0
disk_read_error:  db 'disk read failed', 0
boot_disk:        db 0

; ----------------------------

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

【讨论】:

    猜你喜欢
    • 2017-08-10
    • 2016-02-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-06
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 2022-01-25
    相关资源
    最近更新 更多