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,2

    Jetzt 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 nicht 🙂

    Eigentlich 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 while

    durchaus interessant, direkt die Adresse hochzuzählen. Jetzt kapier ich auch erst, was die [bla + x]-Option tut.

    thx für diese Anregung!


Anmelden zum Antworten