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

汇编实现原地数组反转:EDI寄存器地址异常问题排查

问题分析与修正方案

EDI地址错误的核心原因

你的myArray是DWORD(32位)类型,每个元素占4字节。SIZEOF myArray返回的是数组总字节数(4个元素×4=16),执行add edi, arrSize后,EDI指向的是数组末尾之后的内存地址,而非最后一个元素的地址。要定位到最后一个元素,需要在总字节数基础上减去单个元素的字节数(TYPE myArray,即4)。

其他需要修正的错误

  • 交换逻辑错误:movzx edi, al和mov esi, bl是直接覆盖地址寄存器(EDI、ESI),而非修改内存中的元素值。正确操作是把寄存器的值写入对应内存地址。
  • 指针未移动:注释掉的inc esi和dec edi必须恢复,否则循环会一直操作同一组地址,无法完成反转。
  • 寄存器位数不匹配:用8位寄存器(AL、BL)只会交换元素的低字节,数组元素是32位DWORD,需用32位寄存器(EAX、EBX)完整交换。

修正后的代码

; reverse an array in place

.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD

.data
myArray DWORD 12h, 34h, 56h, 78h
arrSize DWORD ?

.code
main PROC
    mov arrSize, SIZEOF myArray
    mov ecx, LENGTHOF myArray/2  ; 循环次数为元素数量的一半
    mov esi, OFFSET myArray       ; ESI指向数组首元素
    mov edi, esi
    add edi, arrSize
    sub edi, TYPE myArray         ; 减去单个元素字节数,指向最后一个元素
    L1:
        ; 保存首尾元素到32位寄存器
        mov eax, [esi]
        mov ebx, [edi]
        ; 交换内存中的元素
        mov [edi], eax
        mov [esi], ebx
        ; 移动指针:首指针后移一个元素,尾指针前移一个元素
        add esi, TYPE myArray
        sub edi, TYPE myArray
    loop L1
    INVOKE ExitProcess, 0
main ENDP
END main

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:20:12