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

汇编调用printf打印ASCII字符触发段错误的原因及解决方法

错误原因
  • 不符合x86-64 System V ABI的printf传参规则:printf的第一个入参(对应rdi寄存器)必须是指向格式化字符串的合法内存地址,你当前直接将待打印的ASCII字符值存入rdi,相当于把ASCII编码的数值当作内存指针访问,该地址几乎都属于不可读的非法地址,直接触发段错误。
  • 其余逻辑中,可变参数函数调用前将%rax置0的操作是正确的,无需修改。
修复方案

打印单个字符需要先定义对应格式化字符串,再按规则传参:

  1. 在数据段定义打印字符用的格式化字符串,示例:
.data
fmt_char: .string "%c"
# 如需打印后自动换行可改为 .string "%c\n"
  1. 调整传参逻辑:rdi存格式化字符串地址,第二个参数rsi存待打印的ASCII字符,调用前保证栈16字节对齐,示例代码:
# 假设待打印字符已存储在 %al 中
mov $fmt_char, %rdi      # 第一个参数:格式化字符串地址
movzbl %al, %rsi         # 第二个参数:待打印字符,movzbl用于清除%rsi高位的垃圾值
mov $0, %rax             # 可变参数无向量寄存器传参,%rax置0
sub $8, %rsp             # 对齐栈到16字节(若当前栈已对齐可省略)
call printf
add $8, %rsp             # 恢复栈指针

如果不想单独在数据段定义格式化字符串,也可以将字符串常量压入栈中临时使用,不过可读性和可维护性更低,不推荐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 15:45:05