Newsgroup: it.comp.os.linux.development
Titolo: Getchar in assembler

Sto scrivendo un file di servizio per potere studiare un esame che fa uso
dell'assembler da linux e non usando il GNU assembler da winzozz.
Ho fatto il porting del file di servizio... solo che non riesco a implementare
una funzione importantissima: la lettura di un carattere da tastiera...
Ho usato la syscall read, ma essendo una lettura bufferizzata si aspetta la
pressione del carriage return... a me serve invece intercettare un singolo
carattere...
Qualcuno ha qualche idea? tnx
-- 
| /
| \Byte - Andrea Briganti - kbytesys(at)
tiscali.it
http://www.kbytesystem.fasturl.it
 - ICQ: 40872731
*** Chi non ha rispetto non merita considerazione

 Qualcuno ha qualche idea? tnx
Che device hai aperto? Non credo che a livello di kernel (quindi di 
syscall) un comportamento del genere possa essere accettabile, almeno 
come default. Anzi. A leggere il libro di Rubini, pagina 78
If a process calls read but no data is (yet) available, the process must 
block.
The process is awakened as soon as some data arrives, and that data is
returned to the caller, even if there is less than the amount requested 
in the
count argument to the method.
Questo discorso, IMHO, andrebbe interpretato, anche alla luce di quanto 
scritto poi:
Both these statements assume that there are both input and output 
buffers; in
practice, almost every device driver has them. The input buffer is 
required to avoid
losing data that arrives when nobody is reading.
Ad ogni modo, prova a verificare che il dispositivo utilizzato non abbia 
qualche IOCTL che cambia il tipo di bufferizzazione.
-- 
HappyCactus - Linux User #209744 - LFS User #6046 - >>> SMSPM950 <<<
 
Ci sono 10 categorie di persone al mondo: quelle che capiscono
il sistema binario e quelle che non lo capiscono.

 singolo carattere...
Va benissimo usare la syscall read con edx settato a 1, devi pero' settare 
il terminale in modo particolare per potere intercettare un singolo 
carattere. In C puoi fare una cosa del genere:
struct termios termparam;
tcgetattr(0,&termparam);
termparam.c_cc[VTIME] = 0;
termparam.c_cc[VMIN] = 1;
tcflush(0,TCIFLUSH);
tcsetattr(0,TCSANOW,&termparam);
ora devi solo farlo in assembly (vai trà che è una vaccata)
Ciao buon lavoro
-- 
No matter. Try again. Fail again. Fail better.

 ora devi solo farlo in assembly (vai trą che č una vaccata)
Ma tutte quelle funzioni, non sono funzioni di libreria? Non credo sia 
tanto banale tradurle in syscall, a meno di non capire bene quali ioctl 
usa tale libreria.
Sbaglio?
-- 
HappyCactus - Linux User #209744 - LFS User #6046 - >>> SMSPM950 <<<
              YAGF Member Group >>> 
www.google.com
 <<<


 Sbaglio?
Bhe... ci sto studiando a riguardo... cose simili a quelle funzioni sono di
nelle libc, ma invocabili mediante syscall numero 54 (proprio quelle
dell'ioctl)...
Il problema è che ancora sto studiando sulla scarsa doc che c'e' in giro per
capire come impostarli :)


 carattere...
Le librerie ncurses hanno una funzione del genere.
Prova a vedere come sono implementate e copia/traduci :-)
-- 
Memory is a prism through which yesterday's light is passed.
Massimo Lauria as Gargamella 

 per capire come impostarli :)
per semplificare il tutto puoi fare una roba tipo:
main(){
struct termios prev,curr;
char c;
tcgetattr(0,&prev);
curr=prev;
curr.c_lflag&=~(ICANON|ECHO);
tcsetattr(0,TCSADRAIN,&curr);
read(0,&c,1);
tcsetattr(0,TCSANOW,&prev);
}
compili, esegui e fai strace per capire che chiamate ioctl utilizza, poi 
implementi in asm.
Otterrai qualcosa simile a:
<cut>
ioctl(0, SNDCTL_TMR_TIMEBASE, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_STOP, {B38400 opost isig -icanon -echo ...}) = 0
read(0, "a", 1)                         = 1
ioctl(0, SNDCTL_TMR_START, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE, {B38400 opost isig icanon echo ...}) = 0
_exit(0)                                = ?
Si tratta solo di cambiare alcuni bit della struct termios e impostare di 
nuovo gli attributi del terminale (che di default in unix è bufferizzato), 
con and e or e not te la cavi con semplicità (potresti anche andare a 
settare i bit con bts o btr ma forse è +semplice la strada di and & C.)
Spero di essere stato 1po' piu' chiaro e utile dell'altra volta.
Ciao
