PDA

View Full Version : [C & ASSEMBLY] Problema con la stampa stringa


FraRu_99
24-10-2014, 17:16
Ciao, spero possiate aiutarmi con il mio problema.
Volevo provare a stampare una stringa da un programma che gira senza sistema operativo.
codice:

__asm__(".code16;");
__asm__("jmpl $0x0000, $main;");

void printchar(const char var){
__asm__ __volatile__ ("int $0x10" : : "a"(0x0e00 | var), "b"(0x0007));
}
void print(char* stringa){
char* var=stringa;
while(*var != '\0'){
printchar(*var);
++var;
}
}
void main() {
print("ciao");
}

il problema è che stampa solo una "S" se uso print("ciao"), mentre se provo a stamare un singolo carattere funziona perfettamente.
Spero possiate aiutarmi, grazie in anticipo.
PS: Il compilatore è GCC sotto ubuntu

monte.cristo
24-10-2014, 21:46
Vado mooolto a memoria perchè è passata davvero una vita da quando mi piaceva fare esperimenti con gli interrupt e la memoria video. :D
All'interno dell'interrupt 10 ci sono due servizi che puoi usare: uno per leggere e l'altro per cambiare la posizione del cursore.
Penso che tu debba usarli per modificare esplicitamente la posizione prima di scrivere il carattere successivo

FraRu_99
24-10-2014, 22:21
Grazie per la risposta.
Ho fatto diversi test cambiando cose qua e la all'interno del codice in c e ho notato che se la stringa da stampare é passata dalla funzione allora stampa "S", ma se la stringa all'interno della funzione print é statica allora stamperà la stringa data . ad esempio
void print(){
char* str="prova";
while(*str != '\0'){
........
}
}
Allora stamperà "Prova"
Altrimenti se la funzione é generica
void print(char* str){
while(*str != '\0'){
........
}
}
Allora stampa "S".
Sto impazzendo:muro: spero tanto di essere riuscito a spiegarmi

monte.cristo
25-10-2014, 12:54
Si, ti sei spiegato. Hai provato a vedere se nelle varie funzioni la stringa è quella corretta?
Nel main infatti tu dichiari la stringa che vuoi stampare ma Hai verificato che all'interno della funzione print il parametro passato sia uguale alla stringa corretta e che abbia il terminatore?
Se in quella funzione è tutto ok, poi verifica che i caratteri passati volta per volta alla printchar siano quelli giusti.

FraRu_99
26-10-2014, 14:51
__asm__(".code16\n");
__asm__("jmpl $0x0000, $main\n");
void printch(char v){
__asm__ __volatile__ ("int $0x10" : : "a"(0x0e00 | v), "b"(0x0007));
}
void print(char* vari){
char* pro="AAAA";
if(vari==pro){
printch('T');
}else{
printch('F');
}
while(*vari!='\0'){
if(*vari=='A'){
printch('A');
}else{
printch('B');
}
++vari;
}
}
void main() {
print("AAAA");
}
Così mi dice che le stringhe sono diverse
__asm__(".code16\n");
__asm__("jmpl $0x0000, $main\n");
void printch(char v){
__asm__ __volatile__ ("int $0x10" : : "a"(0x0e00 | v), "b"(0x0007));
}
void print(char* vari){
char* pro="AAAA";
if(vari==pro){
printch('T');
}else{
printch('F');
}
}
void main() {
print("AAAA");
}
così mi dice che sono uguali.
:confused: :confused: :confused: :confused: :confused: :confused: :confused: :confused: :confused: :confused: :confused:

Daniels118
27-10-2014, 13:27
Non conosco la sintassi che hai utilizzato nel codice assembly (cosa significano quei due punti?), ma si direbbe che stai generando l'interrupt prima di aver valorizzato i registri, forse dovresti invertire l'ordine delle istruzioni.

Il tentativo di verificare il valore della stringa nel post successivo è implementato male, l'operatore == in quel caso effettua un contronto tra i puntatori, non tra le stringhe, mi sorprende che in uno dei due casi ti dice che sono uguali; usa strcmp.

FraRu_99
27-10-2014, 22:20
I due punti servono proprio per valorizzare i registri, per quanto riguarda la funzione domani la provo. Grazie

Daniels118
28-10-2014, 10:31
Ma se scrivi nel main:

printch('c');
printch('i');
printch('a');
printch('o');

funziona?

FraRu_99
28-10-2014, 12:24
Si

Daniels118
28-10-2014, 13:07
Quindi la routine printch dovrebbe essere corretta. Al fine di diagnosticare il problema prova a modificare print così:
void print(char* stringa){
char* var=stringa;
printf("%s", var);
}
E poi così:
void print(char* stringa){
char* var=stringa;
while(*var != '\0'){
printf("%c", *var);
++var;
}
}

FraRu_99
28-10-2014, 21:19
Purtroppo così non funziona:cry:

Daniels118
29-10-2014, 09:08
Non funziona né nel primo né nel secondo caso?
Per "non funziona" intendi dire che stampa una cosa strana o non compila proprio?
Su windows 8 funziona senza problemi, a meno dell'interrupt che ovviamente è disabilitato. Purtroppo non ho un ambiente per fare un test completo :(

FraRu_99
29-10-2014, 18:19
Per non funziona intendo che stampa S.
Ma non capisco perchè non dovrebbe funzionare.
Per testare compilo con gcc ed eseguo con virtual box il tutto sotto ubuntu