DOMANDA Segmentation Fault (Ubuntu 1804)

Pubblicità

JDany

Utente Attivo
Messaggi
467
Reazioni
24
Punteggio
46
Salve. Ho scritto questo programma in C

C:
#include <stdio.h>
#include <stdlib.h>

int main(void){
    
    __asm__("movl $1, %eax;"
           "int $0x80;");
    
    return 0;
}

Quando vado a compilare il programma, nessun errore, per il gcc tutto ok. Però quando eseguo, su Windows il programma parte ma ritorna un errore, mentre su Ubuntu non lo esegue nemmeno.
L'errore in fase di run è questo: "Segmentation fault (core dumped)"

Da cosa è generato e come si può risolvere?
 
Premetto che non conosco il significato dell'istruzione assembler che hai annegato nel codice C, tuttavia gli errori di segmentazione avvengono quando tenti l'accesso a zone di memoria a cui non ti è permesso (dal sistema operativo) accedere, per esempio zone di memoria riservate al kernel del sistema o aree di memoria protette per ragioni di sicurezza (o perché già assegnate ad un altro processo)
 
Premetto che non conosco il significato dell'istruzione assembler che hai annegato nel codice C, tuttavia gli errori di segmentazione avvengono quando tenti l'accesso a zone di memoria a cui non ti è permesso (dal sistema operativo) accedere, per esempio zone di memoria riservate al kernel del sistema o aree di memoria protette per ragioni di sicurezza (o perché già assegnate ad un altro processo)

L'istruzione in Assembly che ho scritto è "equivalente" alla funzione getchar(), cioè aspetta la pressione di un carattere, lo stampa a video e poi chiude il programma.

Quindi in pratica noi non possiamo più usare gli interrupt, dato che il s.o. ne vieta l'utilizzo?
 
L'istruzione in Assembly che ho scritto è "equivalente" alla funzione getchar(), cioè aspetta la pressione di un carattere, lo stampa a video e poi chiude il programma.

Quindi in pratica noi non possiamo più usare gli interrupt, dato che il s.o. ne vieta l'utilizzo?
Conclusione affrettata: se tu scrivessi un programma assembly ti limiteresti a quelle due istruzioni? Magari è la modalità con cui effettui la chiamata che non è adeguata.. prova ad approfondire

Inviato dal mio Nexus 5 utilizzando Tapatalk
 
L'istruzione in Assembly che ho scritto è "equivalente" alla funzione getchar(), cioè aspetta la pressione di un carattere, lo stampa a video e poi chiude il programma.

Quindi in pratica noi non possiamo più usare gli interrupt, dato che il s.o. ne vieta l'utilizzo?
Quel codice assembly corrisponde al return 0 in C (in verità ad un return e basta, dovresti caricare $0 in %ebx se non erro). Per fare quella funzione che hai detto tu dovrebbe essere cosi (sicuro ci son errori eh)
Codice:
/*Varie parti sopra che sticà*/
movl $3, %eax
movl $2, %ebx
movl num, %ecx
movl $5, &edx     
int $0x80

movl $4, %eax
movl $1, %ebx
movl num, %ecx
movl $5, &edx     
int $0x80

movl $1, %eax
int $0x80
Comunque, togli l'int $0x80 e dovresti risolvere. @Andretti60 e @DispatchCode dovrebbero saperne a pacchi.
 
Ultima modifica:
Premetto di non averlo mai utilizzato sotto a Linux.

Int 0x80 è proprio la chiamata di sistema. Mi sembra manchi un parametro, ovvero l'error code (ebx=0).
Questa chiamata di sistema è la exit però, quindi dovresti vedere il programma che si apre e si chiude.

Preciso che è molto probabile che sotto Linux le system call vengano esposte (attraverso le int), e poi internamente venga chiamata syscall.

Per curiosità sotto a Windows, avevo risposto qui: https://forum.tomshw.it/threads/in-che-modo-vengono-realizzate-le-system-call.598525/
 
??? Ma se la chiamata alla funzione è proprio quella! Perché la dovrebbe togliere?..

Inviato dal mio Nexus 5 utilizzando Tapatalk
Pare che $0x80 sia per i sistemi a 32bit, e da segfault perchè il kernel non lo riesce a simulare. La soluzione è usare "syscall" o provare a compilare (in gcc) con -m32 e altre cose
 
Ultima modifica:
Pare che $0x80 sia per i sistemi a 32bit, e da segfault perchè il kernel non lo riesce a simulare. La soluzione è usare "syscall" o provare a compilare (in gcc) con -m32 e altre cose

int 0x80 funziona bene sui 32bit e male con i 64bit a causa degli indirizzi, suppongo. Se è compilata a 32bit la parte alta dei registri (i 32bit importanti) viene posta a 0 anche utilizzando RAX e gli altri.
In teoria dovrebbe funzionare quindi 0x80, ma solo se è nel range dei 32bit. La soluzione corretta però è quella di utilizzare syscall.
 
Pubblicità
Pubblicità
Indietro
Top