汇编实现原地数组反转: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
相关产品推荐
相关产品推荐

