程序集传递BYTE数组

时间:2014-04-11 14:45:26

标签: assembly x86 masm irvine32

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进行比较,但我无法使用过程逐步完成数组。我已经能够在没有程序的情况下完成所有这些并尝试使用程序实现这一点。

1 个答案:

答案 0 :(得分:-1)

有很多问题。该程序甚至没有组装。至少在过程ret结束时缺少validateArrayExitProcess末尾为main,程序结束时为END main 。我猜INVOKE validateArray, ADDR byteArrayLoop 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