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

16位BIOS模式下AT&T汇编:磁盘扇区内容循环打印指令选择咨询

16位BIOS模式下遍历磁盘扇区并打印十六进制值的汇编实现

背景

已通过AT&T汇编实现read_sector函数,利用0x13中断的索引寻址方式将单个磁盘扇区加载到内存地址0xD000起始位置。现需遍历该扇区的所有字节,调用已实现的cons_write_hex函数打印每个字节的十六进制值,可用cx寄存器作为循环计数器,纠结使用jmp还是loop指令实现循环。

现有代码

read_sector:
    movw    $disk_address_packet, %si
    movw    $1, 2(%si)
    movw    $0xD000, 4(%si)
    movw    $1, 8(%si)
    movb    $0x42, %ah
    movb    (boot_device), %dl
    int     $0x13
    jc      read_failed
    
    movb    (0xD000), %al             # 检查扇区是否为空
    cmpb    $0, %al
    je      read_failed

cons_write_hex:
    movw    $4, %cx
    movb    $0x0E, %ah
    
hexloop:
    rol     $4, %bx             # 左移4位
    movw    %bx, %si
    and     $0x000F, %si
    movb    HexChars(%si), %al
    int     $0x10
    loop    hexloop
    ret

解决方案:使用loop指令实现循环

为什么选loop而非jmp

loop是x86架构专为计数循环设计的指令,它会自动完成**cx减1和判断是否为0**的操作:若cx减1后不为0,则跳转到指定标签;若为0则继续执行后续代码。相比手动用jmp实现(需单独写dec %cx、cmp $0, %cx、jnz指令),loop代码更简洁、可读性更强,完全适配用cx做计数器的场景。

遍历扇区并打印的实现代码

; 遍历0xD000起始的扇区,打印每个字节的十六进制值
print_sector:
    movw    $512, %cx          ; 单个磁盘扇区默认512字节,设置循环计数器
    movw    $0xD000, %si       ; 指向扇区的起始内存地址

print_loop:
    pushw   %cx                ; 保存主循环的计数器值(cons_write_hex会修改cx)
    movzbw  (%si), %bx         ; 取出当前字节,零扩展为16位存入bx(cons_write_hex依赖bx传参)
    call    cons_write_hex     ; 调用打印函数
    popw    %cx                ; 恢复主循环的计数器
    incw    %si                ; 指针移动到下一个字节
    loop    print_loop         ; cx减1,不为0则继续循环
    ret

关键注意点

  • cons_write_hex函数内部会修改cx寄存器(将其设为4用于自身的打印循环),因此在调用前必须用pushw %cx保存主循环的计数器值,调用后用popw %cx恢复,避免主循环计数出错。
  • 使用movzbw指令将8位字节零扩展为16位存入bx,确保cons_write_hex处理的是完整的16位寄存器值,避免符号扩展导致的打印错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 10:46:31