MASM:访问冲突写入位置

MASM: Access Violation Writing Location

使用 MASM 8086
程序确定给定数组中的最大值

当 esi 增加时,会抛出未处理的异常。当 largestVal 被定义为 DWORD 时,这似乎不会发生。但是,这会阻止 .IF largestVal < ebx 工作。

Include Irvine32.inc

FindLargest PROTO, pArr: PTR DWORD, Count: DWORD

.data

str1 BYTE "arr1: ", 0
str2 BYTE "arr2: ", 0
str3 BYTE "arr3: ", 0

arr1 SDWORD +1122h, +2233h, -3344h
arr2 SDWORD +2233h, +3344h, +4455h, +6677h

.code

main PROC
call Clrscr

INVOKE FindLargest, ADDR arr1, LENGTHOF arr1
mov edx, OFFSET str1
call WriteString    
call WriteInt       


INVOKE FindLargest, ADDR arr2, LENGTHOF arr2
mov edx, OFFSET str2
call WriteString
call WriteInt

exit
main ENDP

FindLargest PROC USES ebx ecx esi, pArr: PTR DWORD, Count: DWORD
LOCAL largestVal: SDWORD

mov esi, pArr       
mov ecx, Count
mov largestVal, -2147483648

L1:

mov ebx, [esi]

.IF largestVal < ebx

mov largestVal, ebx

.ENDIF

add esi, 4                 ; Where exception gets thrown                
loop L1

mov eax, largestVal         
ret
FindLargest ENDP
END main

这是VS2015的一个特性。该代码适用于 VS2013

Visual Studio 2015 年偶然发现了这条线:

.IF largestVal < ebx

并产生全部废话,其中 largestVal 的地址 ebp-7D 超出了堆栈帧。正确的是 ebp-4.

我找到了两个解决方法。

1) 将 largestVal.IF 指令分离:

...
mov eax, largestVal
.IF eax < ebx
mov largestVal, ebx
.ENDIF
...

2) 不要使用 MASM 预处理器,而是使用纯汇编指令:

...
cmp largestVal, ebx
jge @F                  ; Jump forward to the next @@
mov largestVal, ebx
@@:
...