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

Linux下NASM汇编如何用printf打印递减十六进制数字水平列表

解决方案:用汇编实现循环输出十六进制递减序列(无write系统调用)

既然不能直接硬编码输出字符串,也无法使用write系统调用,我们可以通过循环遍历+十六进制转ASCII+DOS/BIOS中断输出的方式实现需求。以下是具体的x86汇编实现(NASM语法,DOS实模式):

org 0x100          ; COM程序起始地址

start:
    mov cx, 0xF     ; 初始化循环计数器为十六进制F(十进制15)
loop_start:
    mov ax, cx      ; 将当前计数器值传入ax用于ASCII转换
    call hex_to_ascii ; 调用转换子程序,结果存入dl寄存器
    call print_char  ; 输出转换后的字符

    cmp cx, 0       ; 判断当前是否为最后一个数字(0)
    je skip_space   ; 若是0则跳过空格输出
    mov dl, 0x20    ; 空格的ASCII码
    call print_char
skip_space:
    dec cx          ; 计数器递减
    jge loop_start  ; 只要计数器≥0,继续循环

    mov ah, 0x4C    ; DOS程序退出功能
    int 0x21

; 子程序:将ax中0-15的数值转为十六进制ASCII字符,结果存在dl
hex_to_ascii:
    cmp ax, 9
    jle is_digit    ; 数值≤9,转为0-9的ASCII
    add ax, 0x37    ; 数值≥10,转为A-F的ASCII(0xA+0x37=0x41='A')
    jmp convert_done
is_digit:
    add ax, 0x30    ; 转为0-9的ASCII(0+0x30=0x30='0')
convert_done:
    mov dl, al
    ret

; 子程序:输出dl中的ASCII字符(使用DOS中断0x21的0x02功能)
print_char:
    mov ah, 0x02
    int 0x21
    ret

核心逻辑说明

  • 循环控制:用cx寄存器作为循环计数器,从0xF开始递减,通过dec cx和jge loop_start实现循环,直到计数器变为-1时退出。
  • 十六进制转ASCII:通过判断数值大小,分别加上0x30(数字)或0x37(字母)完成转换,完全避免硬编码字符串。
  • 字符输出:使用DOS中断int 21h的0x02功能输出单个字符,而非write系统调用,符合需求。
  • 格式控制:每次输出字符后判断是否为0,若非0则输出空格,保证最终输出格式为F E D C B A 9 8 7 6 5 4 3 2 1 0。

如果需要脱离DOS环境,可改用BIOS视频中断替换输出子程序:

; 替换后的print_char子程序(BIOS实模式输出)
print_char:
    mov ah, 0x0E
    mov bh, 0x00    ; 显示页码
    mov bl, 0x07    ; 文本属性(黑底白字)
    int 0x10
    ret

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:22:43