【问题标题】:Nasm simple bootloader. Call and ret do not work properlyNasm 简单的引导加载程序。 call 和 ret 不能正常工作
【发布时间】:2015-01-08 19:48:41
【问题描述】:

我有这个代码:

;bootloader
[bits 16]
[org 0x7c00]

jmp main

print_char:
    mov ah,0x0e
    mov bh,0x00
    mov al,65
    int 0x10
ret

main:
    call print_char

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

所以,它应该跳转到 main 并调用 print_char 在屏幕上打印一个字母 A,但它不起作用!我正在使用 qemu+gdb 进行测试。我在一开始在 gdb 中设置了几个断点,在调用 print_char 时设置了另一个断点,在 ret 中设置了最后一个断点。我发现这段代码中没有调用 print_char 。我的代码有什么问题?

我的调试会话:

(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x0000fff0 in ?? ()
(gdb) br *0x7c00
Breakpoint 1 at 0x7c00
(gdb) br *0x7c00+0x3
Breakpoint 2 at 0x7c03
(gdb) br *0x7c00+0xb
Breakpoint 3 at 0x7c0b
(gdb) br *0x7c00+0xc
Breakpoint 4 at 0x7c0c
(gdb) stepi
0x0000e05b in ?? ()
(gdb) c
Continuing.

Breakpoint 1, 0x00007c00 in ?? ()
(gdb) stepi

Breakpoint 4, 0x00007c0c in ?? ()
(gdb) stepi
0x00007c0e in ?? ()
(gdb) stepi
0x00007c10 in ?? ()
(gdb) stepi
0x00007c12 in ?? ()
(gdb) stepi
0x00007c15 in ?? ()
(gdb)

第一个文件:

 1                                  ;bootloader
 2                                  [bits 16]
 3                                  [org 0x7c00]
 4                                  
 5                                  
 6 00000000 E90900                  jmp main
 7                                  
 8                                  print_char:
 9 00000003 B40E                        mov ah,0x0e
10 00000005 B700                        mov bh,0x00
11 00000007 B041                        mov al,65
12 00000009 CD10                        int 0x10
13 0000000B C3                      ret
14                                  
15                                  main:
16 0000000C E8F4FF                      call print_char
17                                      
18                                  
19 0000000F 00<rept>                times 510-($-$$) db 0
20         
                     
21 000001FE 55AA                    dw 0xAA55

解决了。

这似乎是坏软盘图像。修复了使用我的二进制文件启动 qemu,例如qemu boot.bin

【问题讨论】:

  • 我能看到的唯一问题是CALL 后面没有代码。为无限循环添加JMP $ 并在qemu 中运行确实会在屏幕上产生预期的字母A。我想你可能会看到gdb 错误。不太擅长调试16位实模式代码。
  • 在调用 print_char 后添加 jmp $ 不会改变任何东西。 Gdb 只是忽略它。
  • 但是只是运行它,你没有打印出A 吗?它应该可以正常工作,这只是一个调试问题。
  • 不,只有“从软盘启动...”和光标在新行上。就这样。问题仍在呼叫指令中 - 它只是不起作用。
  • 它在这里工作正常,即使使用gdb

标签: assembly system nasm bootloader


【解决方案1】:

不是实际问题,而是在 cmets 中提出的问题:

但是如果我想将我的“操作系统”写入软盘并且会有几个文件?

你是:
- 在 Windows 上?
使用免费工具虚拟软盘。但不确定它是如何工作的。
- 在 Linux 上? 使用ddmkfs.fat
dd if=/dev/zero of=floppy.img bs=512 count=2880 将为您制作一张 1.44M 的软盘。
losetup /dev/loop0 floppy.img 将映像连接到设备文件。
mkfs.fat /dev/loop0 将创建 FAT12 文件系统通常用于软盘。 dd if=bootloader.bin of=floppy.img 安装您的引导加载程序。
- 在 OS X 上?
使用hdiutil
hdiutil create -type UDIF -layout NONE -sectors 2880 -fs "MS-DOS FAT12" floppy.img 创建格式化的软盘映像。
dd if=bootloader.bin of=floppy.img 安装引导加载程序。与 Linux 相同。

你应该设置一个BIOS parameter block,否则无法挂载镜像。

让项目继续进行!

【讨论】:

    猜你喜欢
    • 2021-08-13
    • 2022-01-07
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 2013-07-07
    • 2013-07-07
    • 2012-04-14
    相关资源
    最近更新 更多