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

循环中能否用非常量值计算有效地址?NASM汇编报错求助

问题分析与解决方案

核心问题拆解

  1. 寻址模式不合法:x86-64架构不支持[rbp - rdx]这种直接用两个寄存器相减的内存寻址方式,仅允许基址寄存器 + 索引寄存器×比例 + 位移量的组合(位移量可正可负,但不能是两个寄存器直接相减)。
  2. 指令语法错误:NASM中64位环境的整数乘法指令应为imul,而非mult(后者是32位模式下的无符号乘法指令,不符合64位语法要求)。
  3. 逻辑偏差:你原本希望每次将乘数加1(使偏移量递增8),但当前代码在计算出偏移量后直接对偏移量自增,导致下次的乘数被错误设置为偏移量,完全偏离了“每次偏移量+8”的预期。

修正后的代码

filter:
    push rbp
    mov rbp, rsp
    sub rsp, 128

    mov dword [rbp], 1 ; 初始乘数设为1,用dword确保32位整数写入,自动零扩展为64位

save: ; 计算正确地址并保存RSI
    push rdx ; 提前保存RDX寄存器
    mov edx, [rbp] ; 取出当前乘数(用32位寄存器足够,避免高位干扰)
    
    ; 计算偏移量:乘数×8,用左移3位替代乘法,效率更高
    shl rdx, 3 ; 此时rdx = 乘数×8
    
    ; 计算目标地址:先通过寄存器运算得到合法地址
    mov rax, rbp
    sub rax, rdx ; rax = rbp - 偏移量,这是合法的寄存器操作
    mov [rax], rsi ; 将RSI保存到目标地址
    
    ; 更新乘数:取出原始乘数自增后存回
    mov edx, [rbp]
    inc edx
    mov [rbp], edx
    
    pop rdx ; 恢复RDX寄存器
    ret

关键修正说明

  • 寻址问题解决:先通过寄存器运算mov rax, rbp + sub rax, rdx得到合法的目标地址,再通过[rax]访问内存,规避了不合法的直接寄存器相减寻址。
  • 指令修正:用shl rdx,3替代错误的mult rdx,8,既符合64位NASM语法,又比乘法指令更高效;若偏好乘法,也可改为imul rdx, 8。
  • 逻辑修正:更新乘数时,重新取出原始乘数进行自增,确保每次偏移量递增8,避免覆盖之前保存的RSI值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:53:20