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

如何在NASM引导加载器中读取字符输入?(含指令错误排查)

解决引导加载器中汇编操作数错误与变量存储问题

首先,咱们先搞定你遇到的「操作码与操作数组合无效」错误——mov ax, al这条指令之所以报错,是因为x86汇编要求指令的操作数大小必须匹配:ax是16位寄存器,al是8位寄存器,直接把8位值赋值给16位寄存器的语法是不合法的。

正确把AL的值存入AX的方法

要实现把AL的内容放到AX里,有两种简单的方式:

  • 方式一:清空AH寄存器,因为AX是AH(高8位)+ AL(低8位)的组合,清空AH后,AX自然就等于AL的16位零扩展值:
    xor ah, ah  ; 用异或操作快速清空AH,比mov ah,0更高效
    ; 此时AX = 0x00XX,XX就是AL里的字符值
    
  • 方式二:如果你的汇编器支持(比如NASM),可以用零扩展指令movzx,直接把8位值扩展成16位存入AX:
    movzx ax, al  ; 自动把AL的零扩展到AH,AX = 0x00XX
    

引导加载器中存储变量的方案

你提到引导加载器没有.bss段,没法用resb 1定义未初始化变量,这很正常——引导加载器通常是单段的实模式程序,一般只有代码段(或者直接用org 0x7c00指定加载地址),没有专门的未初始化数据段。

咱们可以直接在代码段里定义变量,只要保证整个引导扇区的大小不超过512字节(最后两个字节必须是引导签名0xAA55)就行:

org 0x7c00  ; 指定引导加载器被加载到内存0x7c00处

readInput:
    mov ah, 0h    ; BIOS中断16h的0号功能:读取键盘输入,结果存在AL
    int 16h
    mov ah, 0eh   ; BIOS中断10h的0eh功能:回显字符
    int 10h

    ; 把AL的值存入AX(正确方式)
    xor ah, ah

    ; 定义一个字节变量来存储输入的字符
    input_char db 0  ; 在代码段里直接定义,初始值为0
    mov [input_char], al  ; 把AL的内容存入变量

    ; 后续代码...

; 填充剩余空间,确保总大小为512字节,最后加上引导签名
times 510 - ($ - $$) db 0
dw 0xaa55

需要注意的是,变量要定义在代码的合适位置,不要放在指令中间(否则会被当成指令执行),最好放在代码块的开头或者结尾,只要不影响指令执行就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:16:35