Array-Schleife
-
hallo!
Ich beschäftige mich seit einigen Tagen mit NASM.
Meine ersten Versuche funktionieren auch schon.
Doch ich bekomme ich folgendes nicht raus:Ich habe
stelle db 2
array db 5,2,8,9,2Jetzt möchte ich von "array" die Stelle in al packen, die in "stelle" gespeichert ist, also "8" (dritte Stelle) soll in al geschrieben werden
mov al [array + stelle] funktioniert ja nicht.Gruß
peak
-
Indirekte Adressierung, also im weitesten Sinne Adressierung ueber Variablen/Indizes, bzw. Zeiger funktionieren beim x86 nur ueber Register.
Du musst den Index also zunaechst in ein Register laden, um ihn zur Adressierung/Indizierung in das Array nutzen zu koennen.Wenn du 32Bit-Adressen benutzt, ist es ziemlich egal, welches der Allround-Register du dazu nimmst. Bei 16Bit funktioniert die Adressierung nur mit bestimmten Registern - idR. si, di, bx und bp. Koennte dann zB. so aussehen:
movzx ebx, [stelle] ; Bei "stelle" gespeichertes Byte lesen und in eax laden - uebrige Bits mit 0 auffuellen mov al, [array + ebx]
-
Du musst den Index also zunaechst in ein Register laden, um ihn zur Adressierung/Indizierung in das Array nutzen zu koennen.
Genau das hatte ich mir auch gedacht und
mov al, [array + ebx]
ausprobiert, jedoch beim compilieren eine Fehlermeldung erhalten.
Jetzt geht es; wo die vorherige Fehlermeldung herkam, weiß ich nichtEigentlich geht es mir um eine Schleife, die die Elemente des Arrays nacheinander ausgeben soll.
Dies habe ich jetzt so gelöst:mov ebx, 0 while: cmp ebx, 10 jz endwhile inc ebx mov al, [var + ebx] call print_int jmp while endwhile:
Ist das die beste Lösung?
Gruß
peak
-
Die beste Loesung unter welchem Gesichtspunkt?
Ein Problem an dem Code ist auf jeden Fall, dass das 1. Element im Array so nicht ausgegeben wird. Du solltest zudem darauf achten, dass die Funktion "print_int" keine der benutzten Register veraendert, bzw. diese ggF. vor dem Funktionsaufruf zB. mit "push" sichern und hinterher mit "pop" wiederherstellen.Mein Vorschlag waere:
mov ecx, 10 mov esi, var ; offset von var while: mov al, [esi] inc esi call print_int dec ecx jnz while
-
Ein Problem an dem Code ist auf jeden Fall, dass das 1. Element im Array so nicht ausgegeben wird
Das stimmt; ich habe das "inc" hinter die Ausgabe verlagert.
Du solltest zudem darauf achten, dass die Funktion "print_int" keine der benutzten Register veraendert
Zutat aus meinem Tutorial:
"To simplify I/O, the author has developed
his own routines that hide the complex C rules and provide a much more
simple interface. Table 1.4 describes the routines provided. All of the routines
preserve the value of all registers, except for the read routines."
(http://www.drpaulcarter.com/pcasm/pcasm-book-pdf.zip)
Die Register bleiben also unverändert.Mein Vorschlag waere:
mov ecx, 10
mov esi, var ; offset von var
while:
mov al, [esi]
inc esi
call print_int
dec ecx
jnz whiledurchaus interessant, direkt die Adresse hochzuzählen. Jetzt kapier ich auch erst, was die [bla + x]-Option tut.
thx für diese Anregung!