传递BYTE指针到PROC时出现A2022与A2032错误的原因排查
汇编错误分析与修正
问题背景
要实现将字节数组指针传入PROC执行校验并返回结果,参考方法尝试解引用指针访问数组,但编译时出现两个错误:
A2022 instruction operands must be same size:出现在第36行mov bh, arrA2032 invalid use of register:出现在第37行mov dl, [bh+ecx-1]
用户困惑:误以为arr、指针和寄存器都是8位,为何触发错误?
错误原因
操作数大小不匹配(A2022)
在flat内存模型下,arr:ptr BYTE是32位的内存地址,而bh是8位寄存器,无法将32位值直接存入8位寄存器,mov bh, arr违反了操作数大小一致的要求。非法寄存器寻址(A2032)
x86汇编的内存寻址规则中,基址寄存器必须是32位通用寄存器(如ebx、eax等),不能使用bh这类8位寄存器作为基址。[bh+ecx-1]的写法不符合寻址规范,因此报错。
修正后的代码
INCLUDE Irvine32.inc .386 .model flat,stdcall .stack 4096 ExitProcess proto,dwExitCode:dword .data minArr BYTE 5,2,4,1,3 maxArr BYTE 9,5,8,4,6 pinArr BYTE 6,3,4,3,4 pinArr2 BYTE 5,4,6,2,5 pinArr3 BYTE 6,2,6,2,5 pinArr4 BYTE 7,3,7,3,2 val1 BYTE ? val2 BYTE ? num BYTE ? str1 BYTE "Valid",0 str2 BYTE "Invalid",0 .code Validate_PIN PROC, arr:ptr BYTE mov eax, 0 mov ebx, arr ; 把32位指针存入32位寄存器ebx mov edx, 0 mov ecx, 5 L1: mov al, [minArr+ecx-1] mov bl, [maxArr+ecx-1] mov dl, BYTE PTR [ebx+ecx-1] ; 用32位ebx做基址,BYTE PTR明确访问字节 mov num, dl .IF(num < al) || (num > bl) mov edx, OFFSET str2 mov eax, ecx ; 直接把ecx赋值给eax,无需先清0 ret .ENDIF loop L1 mov edx, OFFSET str1 mov eax, 0 ret Validate_PIN ENDP main PROC invoke Validate_PIN, addr pinArr call WriteString call WriteInt call Crlf ; 加换行让输出更清晰 invoke Validate_PIN, addr pinArr2 call WriteString call WriteInt call Crlf invoke Validate_PIN, addr pinArr3 call WriteString call WriteInt call Crlf invoke Validate_PIN, addr pinArr4 call WriteString call WriteInt call Crlf invoke ExitProcess, 0 ; 程序正常退出 main ENDP END main
关键修改点
- 将
mov bh, arr替换为mov ebx, arr:用32位寄存器存储32位指针,匹配操作数大小 - 将
mov dl, [bh+ecx-1]替换为mov dl, BYTE PTR [ebx+ecx-1]:使用合法的32位基址寄存器ebx,并用BYTE PTR明确指定访问字节类型,避免汇编器歧义 - 补充
invoke ExitProcess, 0保证程序正常退出,添加call Crlf优化输出格式
内容的提问来源于stack exchange,提问作者cptalpdeniz
相关产品推荐
相关产品推荐

