Newsgroup: it.comp.programmare.win32
Titolo: INT21H,con W98,perchè mi dà questo errore?

sto usando dell'assembly inline con vc++
indipendentemente da quello che ho caricato finora nei registri ogni volta
che chiamo i servizi con INT 21H questa istruzione
ottengo un errore
cliccando su dettagli ottengo:
PORTCONT ha provocato un errore di protezione generale
nel modulo KRNL386.EXE in 0001:00008614.
Registri:
EAX=00003516 CS=022f EIP=00008614 EFLGS=00010206
EBX=00558bea SS=0257 ESP=0065fd84 EBP=0065fd88
ECX=00000000 DS=0247 ESI=81d3e964 FS=4c3f
EDX=0078037a ES=0257 EDI=0065fdf8 GS=0000
Byte all'indirizzo CS:EIP:
87 5e fc 8e 5e fe 50 9c 58 f6 c4 02 58 75 01 fb
Immagine dello stack:
02570000 106afdf9 0302024f 00020000 00000257 00000257 fdf8e964 0000037a
00200000 00000000 81d3e964 00550000 cccccccc cccccccc cccccccc cccccccc
sperando sia abbastanza per darmi una mano vi ringrazio

 ottengo un errore
se non ho capito male INT 21H e altre funzioni lavorano a 16 bit quindi un
compilatore a 32 bit non ci andrà d'accordo

blisca (10/09/2007 19.16.59):

Uh... quanti ricordi... :D
Cercando di essere più stringati possibile (perdonate le imprecisioni):
Da quando Intel iniziò a produrre il processore 386, venne implementata
una protezione tramite livelli di esecuzione, i cosiddetti "ring", ed è
da Windows 3.0 che Microsoft usa i ring per implementare la "modalità
protetta".
Tutto il codice che gira nel ring 0 ha accesso diretto all'hardware
(kernel e driver), e controlla tutto quello che i ring più esterni
possono fare. Fino al processore 8086, tutto il codice aveva accesso
completo a tutta la memoria, si era in una specie di ring 0 permanente.
Il 286 era una fase di transito, iniziava ad implementare i selettori
per accedere ad aree di memoria superiori al megabyte di default. Dal
386 in avanti, il ring 0 intercetta tutto, e risponde nel modo migliore
secondo lo sviluppatore del sistema operativo.
Se non ricordo male, in Windows le applicazioni utente girano nel ring
3, quindi non appena tentano un'operazione che il ring 0 non permette
(ad esempio, chiamata diretta di interrupt o l'accesso ad un area di
memoria non permessa), viene generata un'eccezione a livello ring 0,
gestita dal kernel... ed ecco l'origine delle famosissime finestre
titolate "L'applicazione ha effettuato un'operazione non valida" e
simili, come la tua.
Se usi Visual C++, e hai tentato di usare un INT 21H, immagino che tu
stia tentando di compilare un'applicazione per MS-DOS, avendo però
preparato un progetto di tipo Win32 console...
A questo punto hai due strade: o trovi un vecchio compilatore che
generi eseguibili MS-DOS a 16 bit (gestiti da Windows creando una
macchina virtuale 8086) e lasci perdere Visual C++, oppure spieghi cosa
stai tentando di fare con l'INT 21H in modo da trovare qualche API di
Windows che faccia al caso tuo.
-- 
Scientology: se la conosci la eviti, se la conosci non ti uccide...
http://xenu.com-it.net
 - 
http://xenu.freewinds.cx
 - 
http://www.xenu.net
(per rispondere personalmente leva IlDitoDalCulo)
---> 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0 <---

 sono degli esempi funzionanti,possibilmente riferiti a IRQ7?
Su Windows NT e derivati è ancora peggio che su 98.
Per gestire un interrupt in quel modo devi scrivere un driver usando 
le funzioni del DDK che puoi scaricare dal sito microsoft (anche se 
non so se troverai ancora la versione per Windows '98).
Tra l'altro tu stai richiamando un interrupt software che è quello di 
ms-dos e, come giustamente diceva OcchioDiDrago, lo puoi fare solo a 
ring 0 oppure dentro l'emulazione DOS fornita da Windows.
In alternativa ci sono driver "generici" che ti consentono di accedere 
alle locazioni di I/O tramite chiamate al driver. Uno dei più 
utilizzati è GIVEIO che, se non ricordo male, è gratuito. Non so però 
se così ti puoi "attaccare" all'interrupt 7.
Quanto ai tempi di risposta, purtroppo Windows 95/NT e derivati non 
sono sistemi operativi real-time e quindi devi aspettarti ritardi 
anche pesanti in qualsiasi punto dell'esecuzione del tuo codice. Un 
driver può migliorare la situazione, ma non risolvere il problema.
Ci sono delle estensioni real-time per Windows che sono, in pratica, 
un sistema operativo real-time che "ospita" al suo interno Windows.
Oppure puoi rivolgerti a S.O. davvero realtime come QNX, Windows CE, 
VxWorks.
-- 
Valter Minute
(the reply address of this message is invalid)
(l'indirizzo di reply di questo messaggio non è valido)

 wrote in message
Xns99A8635EF39...@193.43.96.1...

Grazie a tutti e due
a questo punto,potrebbe essere utile compilare a 16 bit  con un vecchio
compilatore,e riavviare il pc in MS DOS e fare partire da lì la mia
applicazione?con tutte le scomodità che ne conseguono


Intuizione esatta. Usando il vetusto MS-DOS come unico sistema
operativo attivo (ma ti consiglio il PC-DOS a questo punto), hai a
disposizione l'attenzione completa della macchina, e puoi richiamare
tutti gli interrupt che vuoi, anche leggere/scrivere direttamente sulle
porte I/O. Per maggiore sicurezza, dovresti staccare i dischi fissi e
avviare da floppy, in modo da poter fare davvero quello che vuoi senza
paura di rovinare la tua piattaforma di sviluppo.
Ancora meglio, puoi benissimo usare un vecchio pc (ne trovi quanti ne
vuoi sui giornali di annunci dell'usato) da tenere parallelamente a
quello di sviluppo, al massimo attaccando il monitor a uno o all'altro
pc a seconda dell'uso.
Unico inconveniente: ricordati che in modalità reale (senza ring di
protezione, istruzioni a 16 bit) sei limitato a 640Kbyte di RAM.


 lì la mia applicazione?con tutte le scomodità che ne conseguono
Oppure, come diceva OcchioDiDrago, recuperare un vecchio PC e usare 
quello per le prove.
Se vuoi usare qualcosa di più "moderno" del DOS (ma dipende da cosa 
devi fare con il tuo progetto) puoi scaricarti la versione evaluation 
di Windows CE e provarla su un vecchio PC.
Anche in quel caso è relativamente semplice agganciarsi a interrupt e 
fare I/O e avrai a disposizione un S.O. realtime.
-- 
Valter Minute
(the reply address of this message is invalid)



vi ringrazio per le alternative che proponete
ma un programmatore serio(non io)non realizzerebbe un VXd al proposito?mi
pare sia l'unico tipo di (driver?programma?)che riesca ad accedere a basso
livello

 riesca ad accedere a basso livello
Su Windows XP sicuramente devi passare per un driver (non vorrei 
sbagliarmi, ma i Vxd sono driver per Windows 9X).
Puoi scriverlo tutto tu o appoggiarti su qualcosa di già fatto (vedi 
GIVEIO).
Rimane il fatto che Windows (ne XP ne 9X) non è un sistema operativo 
real-time e, anche scendendo a livello di driver, non puoi garantire 
_sempre_ tempi di risposta affidabili.
Poi, con accorgimenti, trucchi e giochetti, ci puoi pure provare, ma 
non sarà mai una soluzione stabile al mille per cento.
Per quello ci sono le estensioni real-time di Windows o i sistemi 
operativi real-time.


 --
ok,sono sempre + orientato alla soluzione vecchio computer -dos
ma w3.1 non è real time?la comodità del mouse non sarebbe male...
In ogni caso avendo il compilatore per dos, posso debuggarlo sul mio w98?
oppure anche qui appena arriverò a INT 21 H mi si bloccherà tutto?
ho provato in in line assembly e sempre per lo stesso discorso non mi è
possibile neanche caricare un registro puntatore con un indirizzo nell'area
degli INT
grazie ancora

 indirizzo nell'area degli INT
Sono gli svantaggi di un S.O. che protegge la memoria e non lascia che 
un processo acceda a spazi che non gli sono stati assegnati e non gli 
competono. Non è una brutta cosa, se non devi accedere all'hardware...



....
accorgersi che un puntatore sta puntando una zona proibita?Cioè l'assembly
dovrebbe essere + profondo del SO,o è una caratteristica dei x86 di
delimitare una zona di RAM secondo le direttive del SO e mandare un segnale
d'allarme se ciò avviene?

 direttive del SO e mandare un segnale d'allarme se ciò avviene?
La maggior parte dei S.O. utilizza la Memory Management Unit e i 
processi vedono indirizzi virtuali che vengono convertiti in indirizzi 
fisici solo se in quel momento la MMU ha all'interno delle sue tabelle 
di conversione un indirizzo valido corrispondente. Altrimenti viene 
generata un eccezione che il kernel del S.O. gestirà come più gli 
piace (normalmente uccidendo il processo, ma alcuni SO usano accessi 
ad indirizzi ben precisi per richiamare le API).
Inoltre alcuni processori prevedono modalità diverse di esecuzione del 
codice per cui alcune operazioni sono possibili solo a codice che gira 
in modalità privilegiate (supervisore).
Il mapping della MMU e il passaggio tra le modalità è gestito dal S.O.
Non è una caratteristica dell'architettura x86, che la implementa dal 
286 (parzialmente) in poi.
L'assembly non è "più" profondo del S.O., semplicemente scrivendo in 
assembly fai "manualmente" una serie di passaggi che usando linguaggi 
a più alto livello farebbero i compilatori/interpreti/runtime. Alla 
fine il processore esegue sempre e solo codice macchina, 
indipendentemente da come è stato generato!
P.S. mettere il primo pezzo della frase nel subject peggiora la 
leggibilità dei messaggi.


blisca ha scritto:

#define FOOL_MODE_ON
Se il tuo problema è la velocità, ti conviene realizzare una interfaccia 
hardware con un latch set/reset che intercetta il bit, quindi interfacci 
questo bit ad un convertitore seriale e lo leggi "con comodo" tramite un 
semplice programma di I/O poll scritto anche in (absit iniuria verbis) 
Visual Basic.
Prima che tu me lo chieda: non sono in grado di darti ulteriori 
dettagli, non sono un progettista hardware, ma ho lavorato spesso con 
dei pazzi che andavano in giro per il mondo con una valigia da 50Kg di 
ferraglia ed i vestiti di ricambio in uno zainetto...
#undef FOOL_MODE_ON
Andrea

 Andrea
Di nuovo grazie,anche ad Andrea- Quasimodo
scusate errori di netiquette nel precedente post
in effetti all'inizio avevo seguito la strada seriale,il microcontrollore
che voglio fare parlare col PC per farci un ulteriore debugging...ha già
l'interfaccia seriale all'interno,ma mi ero impuntato a realizzare una
comunicazione + veloce,  a costo di usare molti pin in più (ne ha 80)
credo che per ora farò così,il Pc legge dalla parallela,dà un impulso di
strobe tramite un ciclo read modify write del registro controllo EPP,questo
impulso viene immediatamente leltto dal microcontrollore il quale ha un
interrupt di facile gestione,a quel punto il microC manda un altro carattere
sulla EPP ,che manterrà lì fino al successivo interrupt
buona serata