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

如何在16位引导代码中循环调用writeHexByte实现显示及编写writeHexWord

需求说明

已在开机启动阶段通过displayChar实现字符显示,需完成以下开发:

  1. 新增writeHexBytes功能,通过循环调用writeHexByte实现批量字节的十六进制屏幕输出
  2. 完成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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 15:24:02