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

x86_64汇编逐位打印十六进制数函数失效问题排查

问题分析与修复

你的代码存在两个核心问题,导致print_hex函数无法正常输出内容:

1. 未正确接收要打印的十六进制数

_start中把目标十六进制数0x1122334455667788存入了rdi,但print_hex开头直接用mov rax, 1覆盖了寄存器,完全没有使用传入的参数。正确做法是先把rdi的值加载到rax,作为后续处理的原始数据。

2. 调用write系统调用时未指定输出目标

write系统调用要求rdi存储文件描述符,print_newline中设置了rdi=1(标准输出stdout),但print_hex里的syscall前没有做这个操作,导致write不知道要输出到哪里。

修复后的代码

section .data

newline_char: db 10
codes: db '0123456789abcdef'

section .text
global _start

print_newline:
    mov     rax, 1                  ; syscall write id
    mov     rdi, 1                  ; stdout file id
    mov     rsi, newline_char       ; data for the syscall write
    mov     rdx, 1                  ; number of bytes to write
    syscall
    ret

print_hex:
    mov     rax, rdi                ; 把传入的十六进制数加载到rax
    mov     rcx, 64                 ; rax shift count

iterate:
    push    rax                     ; 保存rax的初始值到栈
    sub     rcx, 4
    sar     rax, cl                 ; 依次右移60、56...0位
    and     rax, 0xf                ; 只保留低4位(一个半字节)
    lea     rsi, [codes + rax]      ; 获取对应的十六进制字符地址

    mov     rax, 1
    mov     rdi, 1                  ; 指定输出到stdout
    mov     rdx, 1                  ; 写入1字节
    push    rcx                     ; 保存rcx,syscall会修改该寄存器
    syscall

    pop     rcx
    pop     rax
    test    rcx, rcx                ; 检查是否处理完所有半字节
    jnz     iterate

    ret

_start:
    mov     rdi, 0x1122334455667788
    call    print_hex
    call    print_newline

    mov     rax, 60
    xor     rdi, rdi
    syscall

关键修正说明

  • print_hex开头新增mov rax, rdi:将_start传入的目标数从rdi转移到rax,作为后续位操作的对象。
  • syscall前新增mov rdi, 1:明确指定write系统调用的输出目标为标准输出。
  • 移除print_hex开头错误的mov rax,1和mov rdx,1,将mov rdx,1移到syscall前,确保每次write都明确写入字节数。

编译运行修复后的代码,会正常输出1122334455667788及换行符。

内容的提问来源于stack exchange,提问作者Fernando de Souza Vasconcelos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:02:32