Frage

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

Ich muss hier ein BYTE-Array verwenden und das Problem, das ich sehe, ist, dass ich nicht in der Lage bin, jedes Element im Array korrekt zu erreichen.Das alles sollte auf das Array zeigen und durch die 1-Byte-Ganzzahlen inkrementieren, aber es ist nicht einmal beim ersten Element und springt dann unerwartet hin und her, als ich debuggte und die Speicheradressen ansah.Ich frage mich, ob mir etwas Offensichtliches entgeht.Ich habe tagelang versucht, die Prozedur dazu zu bringen, jedes Element schrittweise durchzugehen.Das Ziel war ein Vergleich mit dem testArray, aber ich kann das Array nicht mithilfe einer Prozedur durchlaufen.Ich konnte dies alles ohne Verfahren tun und versuche, dies jetzt mit Verfahren umzusetzen.

War es hilfreich?

Lösung

Es gibt viele Probleme.Das Programm wird nicht einmal assembliert.Zumindest fehlt es daran ret am Ende des Verfahrens validateArray, ein ExitProcess am Ende von main und ein END main am Ende des Programms.Ich schätze INVOKE validateArray, ADDR byteArray Und Loop L5 sind Tippfehler.

1) INVOKE validateArray, ADDR byteArray ist offensichtlich ein Tippfehler.Ich schätze, du hast es gemeint testArray und werde es im Folgenden so nennen.

2) byteArray ist eine Stack-Adresse. byteArray[edi] fügt hinzu EDI an diese Adresse (*1 ist überflüssig). mov eax, byteArray[edi ] lädt 4 Bytes vom Stapel.Es enthält den Zeiger auf byteArray Wenn EDI=0 und sonst Mist.Sie müssen zuerst den Wert von laden byteArray um den Zeiger zu bekommen testArray.Dann können Sie es mit Klammern dereferenzieren:

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] lädt 4 Bytes (32 Bits) hinein EAX unabhängig vom bezeichneten Typ.Nach dem ersten Aufruf (korrigiert auf den rechten Zeiger) z.B. EAX enthält die Werte der ersten vier Elemente von testArray:1,2,3,4, habe ihnen Little Endian gegeben: EAX=0x04030201. WriteDec gibt den Dezimalwert „67305985“ aus.Da du es brauchst EAX Verwenden Sie für WriteDec die spezielle x86-Anweisung zum Laden eines Bytes in ein Dword-Register:

movzx eax, byte ptr [esi]

Der Größenbezeichner BYTE PTR teilt dem Assembler mit, dass er ein Byte erweitern soll EAX.MASM kann das nicht wissen, da es auch möglich ist, ein Wort zu erweitern.

Wenn Sie ein vorzeichenbehaftetes Byte zu einem vorzeichenbehafteten Dword (eventuell negativ) erweitern möchten:

movsx eax, byte ptr [esi]

Übrigens:Sie benötigen keine PROTO-Deklaration, wenn Ihr INVOKE „nach oben“ verweist, d. h.Der ValidateArray-PROC ist definiert Vor es wird genannt.

Ich habe Ihren Code ein wenig korrigiert, um ein funktionierendes Programm zu erhalten:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top