You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将C程序编译为nasm -f bin格式并在QEMU中运行?

用C编写裸机引导程序并在QEMU运行的需求

需求概述

我一直在寻找无需使用堆或标准库的简单C程序示例,以及如何编译它们以在QEMU中运行的说明,但尚未找到足够简洁的方案——理想状态是像我现有的汇编Hello World引导加载程序一样小巧,便于修改、重建和重新运行。我可以接受包含大量内联汇编的C程序。

我几乎不了解裸机开发、引导加载程序开发或内核开发,正通过构建各类程序并在QEMU中运行来学习,希望了解如何使用比汇编更高阶的语言编写程序并在QEMU中运行。

工作环境信息

我在Chromebook内的Debian系Linux容器中工作,系统信息如下:

sh:1 $ uname -a
Linux penguin ############## #1 SMP PREEMPT_DYNAMIC Thu, 3 Oct 2024 12:57:30 +0000 x86_64 GNU/Linux

现有汇编引导程序运行情况

我从Wikibooks的一篇文章中获取了一个简单的引导加载程序示例(见附录A),并通过以下命令汇编:

nasm -f bin -o floppy.img preamble.asm

file工具识别出该命令生成的是引导扇区:

floppy.img: DOS/MBR boot sector

我可以通过以下命令启动该镜像:

qemu-system-x86_64 -m 4096 -no-reboot floppy.img 

启动后会打开一个图形窗口,反复无换行打印Hello World!。我想知道是否可以用C而非汇编为该环境编写程序。

附录A:汇编引导加载程序代码

org 7C00h
 
         jmp short Start ;Jump over the data (the 'short' keyword makes the jmp instruction smaller)
 
 Msg:    db "Hello World! "
 EndMsg:
 
 Start:  mov bx, 000Fh   ;Page 0, colour attribute 15 (white) for the int 10 calls below
         mov cx, 1       ;We will want to write 1 character
         xor dx, dx      ;Start at top left corner
         mov ds, dx      ;Ensure ds = 0 (to let us load the message)
         cld             ;Ensure direction flag is cleared (for LODSB)
 
 Print:  mov si, Msg     ;Loads the address of the first byte of the message, 7C02h in this case
 
                         ;PC BIOS Interrupt 10 Subfunction 2 - Set cursor position
                         ;AH = 2
 Char:   mov ah, 2       ;BH = page, DH = row, DL = column
         int 10h
         lodsb           ;Load a byte of the message into AL.
                         ;Remember that DS is 0 and SI holds the
                         ;offset of one of the bytes of the message.
 
                         ;PC BIOS Interrupt 10 Subfunction 9 - Write character and colour
                         ;AH = 9
         mov ah, 9       ;BH = page, AL = character, BL = attribute, CX = character count
         int 10h
 
         inc dl          ;Advance cursor
 
         cmp dl, 80      ;Wrap around edge of screen if necessary
         jne Skip
         xor dl, dl
         inc dh
 
         cmp dh, 25      ;Wrap around bottom of screen if necessary
         jne Skip
         xor dh, dh
 
 Skip:   cmp si, EndMsg  ;If we're not at end of message,
         jne Char        ;continue loading characters
         jmp Print       ;otherwise restart from the beginning of the message
 
 
 times 0200h - 2 - ($ - $$)  db 0    ;Zerofill up to 510 bytes
 
         dw 0AA55h       ;Boot Sector signature
 
 ;OPTIONAL:
 ;To zerofill up to the size of a standard 1.44MB, 3.5" floppy disk
 ;times 1474560 - ($ - $$) db 0

内容的提问来源于stack exchange,提问作者Greg Nisbet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 06:55:13