MASM:访问违规写入位置

时间:2017-04-30 07:05:42

标签: assembly masm irvine32

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

当esi增加时,会抛出未处理的异常。当largeVal定义为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

1 个答案:

答案 0 :(得分:0)

这是VS2015的一个功能。该代码适用于VS2013

Visual Studio 2015偶然发现了这一行:

.IF largestVal < ebx

并产生总废话,其中包括堆栈框架中的ebp-7D的地址largestVal。正确是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
@@:
...