Assembly NASM - Esercizio palindrome

di il
20 risposte

Assembly NASM - Esercizio palindrome

Salve, vorrei capire perché questo breve programma non funziona dato che il ragionamento mi sembra corretto ma nel momento in cui lo si esegue viene restituito il seguente errore: "Command exited with non-zero status 1". Se avete bisogno di compilarlo utilizzate il seguente sito: https://www.jdoodle.com/compile-assembler-nasm-onlin

;Verificare se una parola è palindroma o no (non ottimizzato)
SECTION .text
global  _start
    
_start: ; tell linker entry point.
    mov ecx, len 
    sub ecx, 3 ;dato che bisogna eliminare il ,10,13,0 (non bisogna contarli come caratteri)
    mov edx, string
    _ciclo:
    inc edx
    mov eax, [edx] ;il valore puntato dal puntatore string+len
    mov ecx, [string+ecx] ; copia in ecx la stringa (il puntatore) e non il carattere puntato
    cmp eax, ecx
    jne _stampaNonPalindroma
    LOOP _ciclo ;lo farà per len volte (non ottimizzato)
    jmp _stampaPalindroma

_stampaPalindroma:
    mov ecx, string2
    mov edx, len2
    mov ebx, 1  ; file descriptor (stdout)
    mov eax, 4  ; system call number (sys_write)
    jmp _esci

_stampaNonPalindroma:
    mov ecx, string3
    mov edx, len3
    mov ebx, 1
    mov eax, 4
    jmp _esci
    
_esci:    
    mov     eax, 1
    int     0x80

section .data
string: db "anna",10,13 ;10 line feed, 13 carriage return, 0 null.
len:    equ $-string
string2: db "Palindroma",10,13
len2:   equ $-string2
string3: db "Non Palindroma",10,13
len3:   equ $-string3

20 Risposte

  • Re: Assembly NASM - Esercizio palindrome

    Non ho capito proprio cosa fai. Utilizzi registri a 32 bit per puntare a singoli caeatteri? Descrivi il funzionamento del ciclo passo passo
  • Re: Assembly NASM - Esercizio palindrome

    Allora, ho provato a rifare il codice in modo più chiaro e commentato, spero tu mi possa dire il perché di questo errore.
    ;Verificare se una parola è palindroma o no (non ottimizzato)
    SECTION .text
    global  _start
        
    _start: ; tell linker entry point.
        mov ecx, string ;assegna il puntatore a string a exc
        add ecx, len ;somma string+len e assegnalo a ecx
        sub ecx, 3 ;dato che bisogna eliminare il ,10,13,0 (non bisogna contarli come caratteri)
        mov eax, string ;assegna il puntatore a string a eax
        mov ebx, len ;registro che terrà il conto di quante volte il ciclo è stato fatto
        _ciclo:
        push eax ;si salva il valore di edx nello stack
        push ecx ;si salva il valore di ecx nello stack 
        mov eax, [eax] ;si assegna ad edx il valore da lui puntato
        mov ecx, [ecx] ;si assegna ad ecx il valore da lui puntato
        cmp eax, ecx ;si verifica se sono uguali
        jnz _stampaNonPalindroma
        pop ecx ;si riprende il valore inizialmente salvato nello stack
        pop eax ;si riprende il valore inizialmente salvato nello stack
        inc eax ;si decrementa il valore di eax (del puntatore) per potere controllare la cella puntata da string+len-3-n (n varierà ogni volta)
        dec ecx ;si decrementa il valore di ecx (del puntatore) per potere controllare la cella puntata da string+len-3-n (n varierà ogni volta)
        dec ebx ;si decrementa il valore di ebx in modo tale da ripetere il ciclo len volte
        cmp ebx,0h ;si verifica se il ciclo è stato ripetuto len volte
        jnz _ciclo
        jmp _stampaPalindroma ;se uscirà "indenne" dal ciclo vuol dire che la parola è palindroma
    
    _stampaPalindroma:
        mov ecx, string2
        mov edx, len2
        mov ebx, 1  ; file descriptor (stdout)
        mov eax, 4  ; system call number (sys_write)
        jmp _esci
    
    _stampaNonPalindroma:
        mov ecx, string3
        mov edx, len3
        mov ebx, 1
        mov eax, 4
        jmp _esci
        
    _esci:    
        mov     eax, 1
        int     0x80
    
    section .data
    string: db "anna",10,13 ;10 line feed, 13 carriage return, 0 null.
    len:    equ $-string
    string2: db "Palindroma",10,13
    len2:   equ $-string2
    string3: db "Non Palindroma",10,13
    len3:   equ $-string3
    
  • Re: Assembly NASM - Esercizio palindrome

    In ogni caso per ora ho utilizzato registri a 32 bit per evitare errori derivanti da bit mancanti, pur sapendo che non è il meglio per non dire altro.
  • Re: Assembly NASM - Esercizio palindrome

    È tutto sballato!
    - esiste l'istruzione loop
    - esistono le istruzioni loadsb, loadsw, etc
    - esistono istruzioni cmpsb, etc
    - usa i registri ESI e EDI
    - lo stack non si usa così:
    1) esci lasciandolo occupato
    2) se hai bisogno di salvare qualcosa nello stack usa lo SP

    L'assembly è molto di più di conoscere le singole istruizioni e qualche chiamata al sistema, bisogna capire come funziona il processore.
  • Re: Assembly NASM - Esercizio palindrome

    Ok, il problema è che molte delle istruzioni che hai nominato non le ho fatte.. probabilmente le farò in futuro. Anche per quanto riguarda il lasciare occupato lo stack non è rilevante nel mio caso, poiché al momento sto solo imparando come usare delle istruzioni per creare un "programmino". Vorrei solo capire perché mi da quell'errore là. Un'altra cosa, LOOP agisce sul registro c, io nel compare uso il registro b se noti, in ogni caso secondo te (oltre alle infinite cose che si possono migliorare attraverso le istruzioni che mi hai scritto), cosa causa questo problema?
  • Re: Assembly NASM - Esercizio palindrome

    Devi accedere ai singoli caratteri (byte) e lavorare con quelli. Se continui con i valori a 32 bit non otterrai un codice funzionante
  • Re: Assembly NASM - Esercizio palindrome

    Allora, non riuscendo bene a capire quanto assegnare e dove ho deciso di rifare tutto da capo, per ora ho fatto un codice che controlli solo il primo e l'ultimo carattere della parola ma mi dice che [ch] e [ah] non sono degli indirizzi validi:
    section .text
    
    global _start
    
    _start:
    
        mov ah, string ;ah diventerà il puntatore al primo carattere
        mov ch, string
        add ch, len 
        sub ch, 3 ;non si dovranno contare i ,10,13,0
        mov cx, [ch] ;servono 2 byte dato che alla stringa sono stati assegnati 2B
        mov ax, [ah]
    _esci:
        mov     eax, 1
        int     0x80
    
    section .data
        string db "anna",10,13
        len equ $ -string
  • Re: Assembly NASM - Esercizio palindrome

    Salve, ho sistemato il codice precedentemente postato, l'unico problema è che devo confrontare i due carattere e scrivendo cmp [eax], [ecx] non me lo accetta in quanto si vuole confrontare due locazioni di memoria, qualche consiglio sul come ovviare a questo problema?
  • Re: Assembly NASM - Esercizio palindrome

    Se stai usando eax e ecx per il confronto non hai seguito correttamente i consigli.
  • Re: Assembly NASM - Esercizio palindrome

    Devi sempre leggere una locazione in un registro da 8 bit e confrontare il registro con il byte di memoria puntato con l'altro puntatore. Quale codice usi adesso?
  • Re: Assembly NASM - Esercizio palindrome

    Non ho ben capito come faresti il compare
    ;Verificare se una parola è palindroma o no (non ottimizzato)
    SECTION .text
    global  _start
    
    _start: ; tell linker entry point.
        mov ecx, string ;assegna il puntatore a string a exc
        add ecx, len ;somma string+len e assegnalo a ecx
        sub ecx, 3 ;dato che bisogna eliminare il ,10,13,0 (non bisogna contarli come caratteri)
        mov eax, string ;assegna il puntatore a string a eax
        mov ebx, len ;registro che terrà il conto di quante volte il ciclo è stato fatto
        _ciclo:
        push eax ;si salva il valore di edx nello stack
        push ecx ;si salva il valore di ecx nello stack 
        cmp [eax],[ecx]
        jnz _stampaNonPalindroma
        pop ecx ;si riprende il valore inizialmente salvato nello stack
        pop eax ;si riprende il valore inizialmente salvato nello stack
        inc eax ;si decrementa il valore di eax (del puntatore) per potere controllare la cella puntata da string+len-3-n (n varierà ogni volta)
        dec ecx ;si decrementa il valore di ecx (del puntatore) per potere controllare la cella puntata da string+len-3-n (n varierà ogni volta)
        dec ebx ;si decrementa il valore di ebx in modo tale da ripetere il ciclo len volte
        cmp ebx,0h ;si verifica se il ciclo è stato ripetuto len volte
        jnz _ciclo
        jmp _stampaPalindroma ;se uscirà "indenne" dal ciclo vuol dire che la parola è palindroma
    _stampaPalindroma:
        mov ecx, string2
        mov edx, len2
        mov ebx, 1  ; file descriptor (stdout)
        mov eax, 4  ; system call number (sys_write)
        int 0x80
        jmp _esci
    
    _stampaNonPalindroma:
        mov ecx, string3
        mov edx, len3
        mov ebx, 1
        mov eax, 4
        int 0x80
        jmp _esci
    
    _esci:
        mov     eax, 1
        int     0x80
    
    section .data
    string: db "anna",10,13 ;10 line feed, 13 carriage return, 0 null.
    len:    equ $-string
    string2: db "Palindroma",10,13
    len2:   equ $-string2
    string3: db "Non Palindroma",10,13
    len3:   equ $-string3
  • Re: Assembly NASM - Esercizio palindrome

    Com DUE operazioni... lettura nel registro e compare tra registro e memoria
  • Re: Assembly NASM - Esercizio palindrome

    mov al, [ecx]
        cmp [eax], al
    Una cosa del genere?
  • Re: Assembly NASM - Esercizio palindrome

    Sì ma devi fare attenzione ai registri usati! Non puoi usare contemporaneamente eax e al

    Eax non lo usate come puntatore
Devi accedere o registrarti per scrivere nel forum
20 risposte