Conversion de problème: __asm__ __volatile__
-
21-09-2019 - |
Question
J'ai eu affaire à Nasm sur un environnement Linux depuis un certain temps et cette fonction a très bien fonctionné ... mais maintenant je suis passer à un environnement de fenêtres et je veux utiliser masm (avec VS2008) Je ne peux pas semble obtenir ce travail ...
void outportb (unsigned short _port, unsigned short _data)
{
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
Quand j'écris quelque chose comme ça ...
void outportb (unsigned short _port, unsigned short _data)
{
asm volatile ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
asm est plus reconnu et volatile renvoie une erreur « chaîne », j'ai aussi essayé d'écrire _asm volatile mais je reçois une erreur « erreur de syntaxe assembleur en ligne dans « opcode »; trouvé" type de données »
La solution
En supposant que vous parlez ensemble de commandes x86, voici quelques choses à retenir:
- l'instruction sorties "" outb un octet, ce qui serait équivalent au type "char" ou "unsigned char" en C / C ++. Pour produire un 16 bits (puisque vous utilisez « court non signé ») mot il faut utiliser « outw »
- étant dit, il est recommandé par Intel (et requis par VS) que vous utilisez le mnémonique d'instructions « out » et la taille du port est reconnu à partir de la taille d'opérande. Par exemple "sur dx, ax " serait équivalent pour "outw", alors que "sur dx, al " est équivalent pour "NUM.B"
- sur x86 le "out" instruction nécessite le port et la valeur de délivrer en sortie être placés dans (e) dx et {EAX / hache / al} enregistre respectivement. Alors que Nasm peut le faire pour vous (je n'ai pas le compilateur à portée de main, donc je ne peux pas confirmer que), dans VS vous devez faire de la façon dont il se fait au niveau du processeur.
- il n'y a aucune raison de préciser mot-clé « volatile » avec __asm. Toutes les instructions de montage en ligne provoquent VS compilateur pour désactiver la mise en cache de lecture (ce mot-clé volatile est pour)
Voici le code (en supposant que vous écrivez dans le port 16 bits):
void outportw(unsigned short port, unsigned short data)
{
__asm mov ax, data;
__asm mov dx, port;
__asm out dx, ax;
}
dans le cas où vous écrivez dans le port de 8 bits, le code devrait ressembler à ça:
void outportb(unsigned short port, unsigned char data)
{
__asm mov al, data;
__asm mov dx, port;
__asm out dx, al;
}