INCLUDE Irvine32.inc
.data
testArray BYTE 1,2,3,4,5
array BYTE 5,4,3,2,1
; Definition
validateArray PROTO byteArray:PTR BYTE
.code
main PROC
INVOKE validateArray, ADDR byteArray
main ENDP
validateArray PROC byteArray:PTR BYTE
mov esi, byteArray ; should point to array, but does not
mov edi, 0
call DumpRegs
L1: mov eax, byteArray[edi * 1] ; not 5, the first element in the array as expected
call WriteDec
inc edi
call CrLf
Loop L5
validateArray ENDP
我需要在这里使用BYTE数组,我看到的问题是我无法正确访问数组中的每个元素。这一切应该指向数组并通过1字节整数递增,但它甚至不在第一个元素,然后在我调试和查看内存地址时意外跳转。我想知道我是否遗漏了一些明显的东西。我已经尝试了几天让程序逐步完成每个元素。目标是与testArray进行比较,但我无法使用过程逐步完成数组。我已经能够在没有程序的情况下完成所有这些并尝试使用程序实现这一点。
答案 0 :(得分:-1)
有很多问题。该程序甚至没有组装。至少在过程ret
结束时缺少validateArray
,ExitProcess
末尾为main
,程序结束时为END main
。我猜INVOKE validateArray, ADDR byteArray
和Loop L5
是拼写错误。
1)INVOKE validateArray, ADDR byteArray
显然是一个错字。我想你的意思是testArray
,我会在下面这样称呼它。
2)byteArray
是堆栈地址。 byteArray[edi]
将EDI
添加到此地址(*1
是多余的)。 mov eax, byteArray[edi ]
从堆栈加载4个字节。如果byteArray
= 0,则它将包含指向EDI
的指针。您首先要加载byteArray
的值以获取指向testArray
的指针。然后你可以用括号取消引用它:
mov esi, byteArray ; ESI: pointer to the first byte of testArray
mov eax, [esi] ; EAX: dword value at [ESI]
add esi, 1 ; Pointer to the next byte of testArray
3)mov eax, byteArray[edi * 1]
将4个字节(32位)加载到EAX
,而不管表示的类型如何。在第一次呼叫之后(纠正到右指针),例如EAX
保存testArray
的前四个元素的值:1,2,3,4,得到它们的小端:EAX
= 0x04030201。 WriteDec
将输出十进制值“67305985”。由于WriteDec需要EAX
,所以使用特殊的x86指令将字节加载到dword寄存器中:
movzx eax, byte ptr [esi]
大小指定符BYTE PTR
通知汇编程序它应将一个字节扩展为EAX
。 MASM无法知道,因为它也可以扩展一个词。
如果要将带符号的字节扩展为带符号的双字(最终为负):
movsx eax, byte ptr [esi]
BTW:如果您的INVOKE指的是“向上”,则不需要PROTO声明,即在调用之前定义的validateArray-PROC。
我纠正了你的代码以获得一个有效的程序:
INCLUDE Irvine32.inc
.data
testArray BYTE 1,2,3,4,5
.code
validateArray PROC byteArray:PTR BYTE
mov esi, byteArray
mov ecx, SIZEOF testArray ; ecx is needed for loop!
_Loop:
movzx eax, byte ptr [esi] ; movzx: load one unsigned byte in a 32-bit-register
call WriteDec
call CrLf
add esi, 1
loop _Loop
ret
validateArray ENDP
main PROC
INVOKE validateArray, ADDR testArray
INVOKE ExitProcess, 0
main ENDP
END main