appel système depuis un assemblage en ligne GCC

Est-il possible d’écrire un seul caractère en utilisant un appel système depuis un bloc d’assemblage en ligne? si c’est le cas, comment? Ça devrait ressembler a quelque chose comme ca:

__asm__ __volatile__ ( " movl $1, %%edx \n\t" " movl $80, %%ecx \n\t" " movl $0, %%ebx \n\t" " movl $4, %%eax \n\t" " int $0x80 \n\t" ::: "%eax", "%ebx", "%ecx", "%edx" ); 

80 $ est «P» en ASCII, mais cela ne retourne rien.

des suggestions très appréciées!

Quelque chose comme

 char p = 'P'; int main() { __asm__ __volatile__ ( " movl $1, %%edx \n\t" " leal p , %%ecx \n\t" " movl $0, %%ebx \n\t" " movl $4, %%eax \n\t" " int $0x80 \n\t" ::: "%eax", "%ebx", "%ecx", "%edx" ); } 

Add : notez que j’ai utilisé lea pour charger l’adresse effective du caractère dans le registre ecx ; pour la valeur de ebx j’ai essayé $ 0 et $ 1 et cela semble fonctionner quand même …

Évitez d’utiliser des caractères externes

 int main() { __asm__ __volatile__ ( " movl $1, %%edx \n\t" " subl $4, %%esp \n\t" " movl $80, (%%esp)\n\t" " movl %%esp, %%ecx \n\t" " movl $1, %%ebx \n\t" " movl $4, %%eax \n\t" " int $0x80 \n\t" " addl $4, %%esp\n\t" ::: "%eax", "%ebx", "%ecx", "%edx" ); } 

NB: cela fonctionne à cause de l’endianité des processeurs intel! :RÉ

Vous pouvez utiliser des contraintes spécifiques à l’architecture pour placer directement les arguments dans des registres spécifiques, sans avoir besoin des instructions movl dans votre assemblage en ligne. De plus, vous pouvez alors utiliser l’opérateur & pour obtenir l’adresse du caractère:

 #include  void sys_putc(char c) { // write(int fd, const void *buf, size_t count); int ret; asm volatile("int $0x80" : "=a"(ret): "a"(SYS_write), "b"(1), "c"(&c), "d"(1)); } int main(void) { sys_putc('P'); sys_putc('\n'); } 

(Dans ce cas, =a(ret) est nécessaire pour indiquer que les appels système EAX .)

 $ cc -m32 sys_putc.c && ./a.out P 

Vous pouvez également renvoyer le nombre d’octets écrits renvoyés par l’appel système et utiliser "0" comme contrainte pour indiquer à nouveau EAX :

 int sys_putc(char c) { int ret; asm volatile("int $0x80" : "=a"(ret) : "0"(SYS_write), "b"(1), "c"(&c), "d"(1)); return ret; } 

IIRC, deux choses ne vont pas dans votre exemple. Premièrement, vous écrivez en stdin avec mov $ 0,% ebx. Deuxièmement, write prend un pointeur en tant que deuxième argument. Par conséquent, pour écrire un seul caractère dont vous avez besoin, stocké quelque part en mémoire, vous ne pouvez pas écrire la valeur directement dans ecx

ex:

 .data char: .byte 80 .text mov $char, %ecx 

Je n’ai fait que du pur asm sous Linux, jamais en-ligne avec gcc, vous ne pouvez pas déposer de données au milieu de l’assemblage. Je ne suis donc pas sûr de savoir comment obtenir le pointeur en utilisant un assemblage en ligne.

EDIT: Je pense que je viens de me rappeler comment faire. vous pouvez pousser ‘p’ sur la stack et utiliser% esp

 pushw $80 movl %%esp, %%ecx ... int $0x80 ... addl $2, %%esp