Zeichenkette nur ein bestimmtes Zeichen ausgeben



  • Hallo,
    ich habe vor kurzem angefangen mich ein wenig mit Assembler zu beschäftigen. Nur komm ich oft bei kleinen Problmenen nicht weiter.
    Derzeit versuch ich von einer Zeichenkette "XFD" nur einen Buchstaben auszugeben.

    Ich kenne das aus Pascal das man da "Zeichenkette[0]" für den ersten Wert angeben konnte. Wie funktioniert das in Assembler? Bzw. wie muss ich meinen Code verändern?
    Ich nutze unter Ubuntu nasm

    section .data
    
    neu db "XFD"
    
    section .text
    global _start
    _start:
    
    mov eax,4
    mov ebx,1
    mov ecx,neu 
    mov edx,3
    int 0x80
    
    mov eax, 1
    mov ebx, 0
    int 0x80
    


  • Um per "int 0x80 Funktion 4" ein einzelnes Zeichen auszugeben setzt Du die Laenge in edx auf 1 und die Adresse des entsprechenden Zeichens in ecx.
    Zur Adressierung ein einfaches Beispiel:

    neu db "XFD"
    
    mov ecx,neu     ; ecx= Adresse des ersten Zeichens im String
    
    mov al,[ecx]    ; 'X'
    mov al,[ecx+1]  ; 'F'
    mov al,[ecx+2]  ; 'D'
    mov al,[ecx+3]  ; '\0'
    
    add ecx,2       ; Adresse zwei Zeichen weiter zeigen lassen
    mov al,[ecx]    ; 'D'
    mov al,[ecx+1]  ; '\0'
    


  • Danke.

    Da ich das ausgeben möchte muss ich ja eax bzw das 8 Bit Register al mit 4 überschreiben. Deshalb die Speicherung von al in eine Variable.

    Nur funktioniert das irgendwie nicht.
    Ich bekomm folgende Fehlermeldung: 4: error: comma or end of line expected

    section .data
    
    neu db "XFD"
    test db 0
    
    section .text
    global _start
    _start:
    
            mov ecx, neu
            mov al, [ecx]
            mov test, al
    
            mov eax, 4
            mov ebx, 1
            mov ecx, test
            mov edx, 1
            int 0x80
    
            mov eax, 1
            mov ebx, 0
            int 0x80
    


  • Du verstandest mich miss, das beispielhafte "mov al,..." sollte Dir lediglich aufzeigen, an welcher Adresse welches Zeichen zu finden ist.
    Denn ecx erwartet nicht das Zeichen selbst sondern die Adresse des selbigen:

    neu db "XFD"
    mov ecx, neu   ; Adresse von 'X'
    add ecx, 2     ; -> 'D'
    mov eax, 4
    mov ebx, 1
    mov edx, 1     ; ein Zeichen ausgeben
    int 0x80
    


  • Jetzt hab ichs verstanden. Zumindest mit der Ausgabe. Danke dafür!
    Demnach variable als solches ist die Adresse im HS
    und [variable] ist der Inhalt.

    Was ich eigentlich machen wollte ist eine 2 Stellige Zahl einlesen und diese dann addieren. Bsp.: Einlesen: 12 - 1+2=3 - Ausgabe: 3


    Genau so das beschreiben einer Variable funktioniert auch nicht so wie ich mir das vorstelle.

    variable db 0
    
    mov eax, 10
    mov variable, eax ;<-- Fehler
    
    section .data
    
    zahl db 0
    len equ $-zahl
    
    section .text
    global _start
    _start:
    
    ;EINLESEN
            mov eax, 3
            mov ebx, 0
            mov ecx, zahl
            mov edx, 2
            int 0x80
    
    ;BERECHNEN
    
            ;lese Stelle 1 zahl und schreibe in eax
            ;addiere Stelle 2 zu eax
            ;schreibe eax zurück in zahl
    
    ;AUSGABE
            mov eax, 4
            mov ebx, 1
            mov ecx, name
            mov edx, len
            int 0x80
    
    ;BEENDEN
            mov eax, 1
            mov ebx, 0
            int 0x80
    


  • variable db 0
    mov eax, 10
    mov variable, eax ;<-- Fehler
    

    Die Variable "variable" ist 8 und das Register "eax" 32 Bit gross.
    Du kannst also nur einen Teil des Registers in der Variablen ablegen:

    variable db 0
    mov variable, al
    

    Desweiteren ist ein Byte etwas wenig um zwei Zeichen einzulesen.
    Auch musst Du die eingelesenen Ascii-Zeichen noch in Ziffern wandeln.



  • So ich hab es gerade nochmal probiert

    var db 0
    mov al, 2
    mov var, al
    

    egal was ich mache ich bekomme "error: invalid combination of opcode and operands"

    Ich habe mir 2 Bücher ausgeliehen dort steht es auch mit mov Variable, Register drin.

    ---

    Das Umwandeln der ASCII-Zeichen fällt ja eigentlich weg, da ich in meinem Fall nur Zahlen einlese.

    ---

    Dennoch bleibt dann das Zahlen Trennproblem. Wenn ich 23 einlese wird das ja sicher als 0001 0111 angesehen, falls die Variable db definiert ist.
    Ich muss das ja vorher als 2 0000 0010 und 3 0000 0011 definieren ohne das jetzt einzeln einzulesen. Nur hab ich keine Idee wie ich das machen kann. Hinzu kommt ja noch das oben erwähnte Problem etwas zurück zu speichern.

    Seit Assembler bin ich das erste mal mit meinem Latein am ende.



  • error: invalid combination of opcode and operands

    mov [var], al
    

    Das Umwandeln der ASCII-Zeichen fällt ja eigentlich weg, da ich in meinem Fall nur Zahlen einlese.

    Du gibst zwar nur Ziffern ein, erhaelst aber eine Zeichenfolge.
    Bei "23" also '2','3' = 50,51.



  • Dumme Frage aber könntest du mir das ein wenig mit einem Beispiel untermauern. Also das mit den Zahlen?



  • Guck Dir doch mal die Ascii-Tabelle an.



  • Danke für deine Hilfe!

    section .data
    
    var db 2, 3
    buffer db 0
    
    section .text
    global _start
    _start:
    
    mov ebx, var
    mov al, [ebx]
    add al, 48
    mov [buffer], al
    push ebx
    
    mov eax, 4
    mov ebx, 1
    mov ecx, buffer
    mov edx, 1
    int 0x80
    
    pop ebx
    add ebx, 1
    mov al, [ebx]
    add al, 48
    mov [buffer], al
    
    mov eax, 4
    mov ebx, 1
    mov ecx, buffer
    mov edx, 1
    int 0x80
    
    mov eax, 1
    mov ebx, 0
    int 0x80
    

Anmelden zum Antworten