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

如何在x64汇编中在栈上声明局部数组并实现遍历求和?

在x64汇编栈上实现局部数组遍历求和的问题解决

你遇到的核心问题是栈上数组的寻址计算错误,以及循环逻辑的疏漏,以下是具体分析和修正方案:

原代码问题分析

  1. 寻址错误:栈向下增长,局部数组元素都在%rbp的负偏移位置(如arr[0]是-8(%rbp),arr[4]是-40(%rbp)),但你用的(%rbp, %rcx, 8)计算的是%rbp + %rcx*8,指向的是%rbp上方的栈空间,完全不是数组元素。
  2. 循环逻辑漏洞:初始%rcx=5,判断cmp $1, %rcx就跳转结束,只会执行4次循环,漏掉一个数组元素。

修正方案

方案1:用寄存器保存数组起始地址(推荐)

将数组的最低地址(最靠近栈顶的arr[4],即-40(%rbp))加载到寄存器,通过正索引配合scaled index遍历:

...
     subq $128, %rsp
     movq $100, -8(%rbp)  # arr[0] = 100
     movq $79, -16(%rbp)  # arr[1] = 79
     movq $85, -24(%rbp)  # arr[2] = 85
     movq $62, -32(%rbp)  # arr[3] = 62
     movq $91, -40(%rbp)  # arr[4] = 91
     movq $0, -48(%rbp)   # sum = 0
     lea -40(%rbp), %rbx  # 把数组最低地址存入%rbx
     movq $0, %rcx        # 遍历索引从0到4
 loop:
     cmp $5, %rcx         # 遍历完5个元素就结束
     jge done
     movq (%rbx, %rcx, 8), %rax  # 取%rbx + 8*%rcx地址的元素
     addq %rax, -48(%rbp) # 累加到sum
     addq $1, %rcx        # 索引自增
     jmp loop
 done:
     ...

方案2:通过调整寄存器地址遍历

无需scaled index,直接移动寄存器地址来逐个访问数组元素:

...
     subq $128, %rsp
     movq $100, -8(%rbp)  # arr[0] = 100
     movq $79, -16(%rbp)  # arr[1] = 79
     movq $85, -24(%rbp)  # arr[2] = 85
     movq $62, -32(%rbp)  # arr[3] = 62
     movq $91, -40(%rbp)  # arr[4] = 91
     movq $0, -48(%rbp)   # sum = 0
     lea -8(%rbp), %rbx   # 把arr[0]的地址存入%rbx
     movq $5, %rcx        # 设置循环次数为5
 loop:
     movq (%rbx), %rax     # 取出当前元素
     addq %rax, -48(%rbp) # 累加到sum
     subq $8, %rbx         # 地址减8,移动到下一个元素(栈向下增长)
     subq $1, %rcx        # 循环次数减1
     jnz loop             # 次数不为0则继续循环
 done:
     ...

补充说明

x64汇编的scaled index模式不支持负scale因子,所以无法直接通过(%rbp, %rcx, -8)来寻址负偏移的数组元素,用寄存器保存起始地址或直接调整地址是更可靠的解决方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:25:13