Assembly übergibt das BYTE-Array mit einer Prozedur
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.
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