如何在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
相关产品推荐
相关产品推荐

