如何在16位引导代码中循环调用writeHexByte实现显示及编写writeHexWord
需求说明
已在开机启动阶段通过displayChar实现字符显示,需完成以下开发:
- 新增
writeHexBytes功能,通过循环调用writeHexByte实现批量字节的十六进制屏幕输出 - 完成
writeHexWord功能开发
接口要求
writeHexByte:接收8位寄存器参数,内部调用convertHexNibble转换后通过写字符接口显示writeHexWord:接收16位寄存器或内存参数,逐字节调用writeHexByte完成显示
最终目标
字符输出完成后,通过循环调用writeHexBytes输出writeChar宏对应的机器码。
实现说明
核心修改点如下:
- 补全
writeHexByte宏:拆分8位数据的高低半字节分别转ASCII输出,执行前后新增寄存器上下文保存/恢复逻辑,避免影响主程序寄存器状态 - 新增
writeHexWord宏:拆分16位数据的高低字节,优先输出高字节(符合十六进制阅读习惯),逐字节调用writeHexByte完成输出 - 新增
writeHexBytes宏:传入内存起始地址和长度,循环遍历每一个字节调用writeHexByte输出 - 修复原有
sumArray宏的逻辑错误,新增段寄存器初始化逻辑,确保实模式下内存访问正常
完整可运行代码
# 宏定义部分 .macro convertHexNibble register cmpb $10, \register jl 1f # 处理>=10的情况,转A-F add $0x37, \register jmp 2f # 处理<10的情况,转0-9 1: add $0x30, \register 2: # 此时寄存器中已经是对应ASCII码 .endm .macro writeHexByte register color pusha # 保存所有寄存器上下文 # 先处理高4位 movb \register, %al shrb $4, %al convertHexNibble %al displayChar %al, \color # 再处理低4位 movb \register, %al andb $0x0f, %al convertHexNibble %al displayChar %al, \color popa # 恢复寄存器上下文 .endm .macro writeHexWord val color pusha # 小端模式下先输出高字节(符合阅读习惯) movb \val + 1, %al writeHexByte %al, \color # 后输出低字节 movb \val, %al writeHexByte %al, \color popa .endm .macro writeHexBytes start len color pusha mov \start, %si mov \len, %cx write_bytes_loop: lodsb # 取ds:si指向的字节到al,si自动+1 writeHexByte %al, \color # 可选:输出空格分隔字节,需要的话可在此处添加displayChar $' ', \color loop write_bytes_loop popa .endm .macro displayChar character color mov $0x09, %ah mov \character, %al mov $0x00, %bh mov \color, %bl mov $0x01, %cx int $0x10 .endm # 设置光标位置,默认参数可隐藏光标 .macro moveCursor row = $0xff column = $0xff mov $0x02, %ah mov $0x00, %bh mov \row, %dh mov \column, %dl int $0x10 .endm .macro sumArray array number result pusha mov $\number, %cx # cx作为元素计数器 mov $0, %al # al存储累加和 mov \array, %bx # bx指向数组起始地址 sum_top: add (%bx), %al # 累加当前元素 inc %bx # 数组指针后移 dec %cx # 计数器减1 jnz sum_top # 未遍历完成则继续 movb %al, \result # 存储最终求和结果 popa .endm # 主引导扇区代码 .code16 .text .global _start _start: # 初始化段寄存器,确保实模式下内存访问正常 xor %ax, %ax mov %ax, %ds mov %ax, %es # 测试单字符转换显示 mov $0x06, %al convertHexNibble %al displayChar %al, $0xe3 moveCursor $2, $3 mov $0x0A, %al convertHexNibble %al displayChar %al, $0xe3 moveCursor $2, $5 # 测试数组求和 sumArray $x 4 sum # 显示求和结果的十六进制值 writeHexWord sum, $0xe3 moveCursor $2, $10 # 测试批量输出:显示displayChar宏展开后的前10字节机器码 writeHexBytes $displayChar_code, $10, $0xe3 # 隐藏光标 moveCursor cli hlt # 数据定义 x: .byte 1, 5, 2, 10 sum: .byte 0 # displayChar宏对应的机器码样本,可根据实际编译结果调整 displayChar_code: .byte 0xb4, 0x09, 0x8a, 0x07, 0xb7, 0x00, 0xb3, 0xe3, 0xb9, 0x01, 0x00, 0xcd, 0x10 # 填充引导扇区到510字节,加魔术字 . = _start + 510 .byte 0x55 .byte 0xAA
内容的提问来源于stack exchange,提问作者user7502173
相关产品推荐
相关产品推荐

