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

如何用x86-64 AT&T语法打印数组的每个元素?

问题分析与修复

第一段代码段错误的原因

在x86-64 System V调用约定里,rcx、rsi属于调用者保存寄存器——你调用print_int时,这个函数可能会修改这两个寄存器的值。你的代码调用print_int前没保存rcx(数组地址)和rsi(循环索引)的状态,返回后这俩寄存器的内容被改了,后续访问数组时用了错误的地址或索引,直接触发段错误。

第二段代码的逻辑问题

循环跳转条件写反了:cmpq $5, %rsi之后用je loop,意思是只有当索引等于5时才继续循环。但索引从0开始,第一次加1后变成1,和5不相等,直接跳去exit,只打印了数组第一个元素1,再加上exit里的3,就出现了你看到的13。

修正后的完整代码

解决上述问题,同时遵循调用约定保护寄存器,修正循环逻辑:

.section .data
array:
    .quad 1,2,3,4,5
.section .text
.globl main

main:
    # 把rcx和rsi压栈保存,避免被print_int修改
    pushq %rcx
    pushq %rsi

    leaq array(%rip), %rcx
    movq $0, %rsi

loop_start:
    # 索引到5就退出循环(数组只有0-4四个有效索引)
    cmpq $5, %rsi
    jge loop_end

    movq (%rcx, %rsi, 8), %rdi
    callq print_int
    incq %rsi
    jmp loop_start

loop_end:
    movq $3, %rdi
    callq print_int

    # 恢复之前保存的寄存器
    popq %rsi
    popq %rcx

    # main函数按约定要返回0,保证程序正常退出
    movq $0, %rax
    ret

重要注意点

  1. 寄存器保护:调用外部函数前,必须保存好你要继续使用的调用者保存寄存器,这里用栈来暂存rcx和rsi。
  2. 循环边界:数组有5个元素,索引范围是0到4,所以当rsi等于5时必须停止循环。
  3. main函数返回:按照C调用约定,main需要返回一个整数值,最后加上movq $0, %rax和ret,避免程序退出状态异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 14:17:42