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
相关产品推荐
相关产品推荐

