2010-07-30 25 views
8

J'apprends asm sur Linux (noobuntu 10,04) j'ai obtenu le code suivant au large de: http://asm.sourceforge.net/intro/hello.htmlAssemblée, bonjour question mondiale

section .text 
global _start ;must be declared for linker (ld) 

_start: ;tell linker entry point 

mov edx,len ;message length 
mov ecx,msg ;message to write 
mov ebx,1 ;file descriptor (stdout) 
mov eax,4 ;system call number (sys_write) 
int 0x80 ;call kernel 

mov eax,1 ;system call number (sys_exit) 
int 0x80 ;call kernel 

section .data 

msg db 'Hello, world!',0xa ;our dear string 
len equ $ - msg ;length of our dear string 

Il est un monde simple bonjour. Fonctionne sur Linux + appelle le noyau directement (apparemment). Quelqu'un peut-il expliquer ce qui se passe vraiment ici? Je pense qu'il lit les nombres entiers dans les registres & ebx du processeur enregistre & ecx, edx data et qui définit l'appel système lorsque le noyau est appelé. Si oui, est-ce que différentes combinaisons d'entiers définissent différents appels système quand int 0x80 est appelé?

Je ne suis pas bon avec les pages de manuel, mais j'ai lu tous les liens que je peux trouver, est-ce qu'une page de manuel me dit quelles combinaisons définissent les appels système?

TOUTE aide est appréciée. Une ligne par ligne d'explication serait incroyable ... -Merci à l'avance Jeremy

Répondre

7

Lorsque vous appelez int 0x80, le noyau cherche à déterminer la fonction que vous voulez appeler à la valeur du registre eax (ce qui est le " numéro de syscall "). Selon ce nombre, le reste des registres est interprété comme signifiant des choses spécifiques. Le sys_write appel attend les registres à mettre en place comme suit:

  • eax contient 4
  • ebx contient le descripteur de fichier
  • ecx contient l'adresse des données à écrire
  • edx contient le nombre de octets

Pour plus d'informations, voir Linux System Calls.

+0

Merci beaucoup, c'était mon soupçon et utile néanmoins ... Pouvez-vous me dire où je peux en savoir plus? Ces entiers syscall sont-ils dans les pages man? – Jeremy

+0

Vous devez creuser un peu en profondeur dans les fichiers d'en-tête source Linux pour trouver les numéros d'appel système. Je n'ai pas de machine Linux à portée de main pour le moment, donc je ne peux pas vous dire l'emplacement exact, mais c'est quelque chose comme 'include/asm/syscall.h' dans l'arborescence des sources du noyau. –

+0

merci beaucoup, vous avez été utile. – Jeremy

0

Il y a trop d'appels système pour qu'il y ait une instruction différente pour chacun d'entre eux.

Au lieu de cela, vous appelez l'instruction TRAP. La valeur de eax détermine quel appel système sera appelé. Les autres registres sont les arguments de l'appel système.

Les appels système sont répertoriés dans le noyau.

+0

Merci. Où, exactement, regarde-t-on les appels système dans le noyau? – Jeremy

2
section .text 
global _start ;must be declared for linker (ld) 

Ceci est juste en-tête matériel, la section « texte » d'un programme de montage est juste les instructions de la machine (par rapport aux données, les données en lecture seule, et les sections BSS). La ligne global est semblable à dire que la fonction _start est "publique".

_start: ;tell linker entry point 

mov edx,len ;message length 
mov ecx,msg ;message to write 
mov ebx,1 ;file descriptor (stdout) 
mov eax,4 ;system call number (sys_write) 
int 0x80 ;call kernel 

D'après les commentaires que nous savons que nous regardons la fonction sys_write, afin que nous puissions man 2 write pour obtenir les détails. Le prototype C donne les paramètres suivants: fd, *buf et count. En commençant par% ebx, nous voyons que ceux-ci correspondent (% ebx = fd,% ecx = chaîne à écrire, et% edx = longueur de chaîne). Ensuite, puisque nous sommes un processus utilisateur, nous devons demander au noyau d'effectuer la sortie. Cela se fait via l'interface SYSCALL, et la fonction write() est (apparemment) donnée le numéro 4. INT 0x80 est une interruption logicielle qui appelle la routine SYSCALL du noyau Linux.

Vous pouvez trouver les numéros réels de tous les syscalls dans les fichiers d'en-tête Linux (en supposant que vous les ayez installés). Sur mon système, j'ai vérifié /usr/include/sys/syscall.h menant à /usr/include/asm/unistd.h, puis sur /usr/include/asm-i386/unistd.h. Où (je vois), #define __NR_write 4.

mov eax,1 ;system call number (sys_exit) 
int 0x80 ;call kernel 

Comme les deux dernières lignes du segment antérieur, il charge juste l'id syscall et fait l'interruption du logiciel pour quitter le programme (supprimer c'est la cartographie de la mémoire et le nettoyage).

section .data 

msg db 'Hello, world!',0xa ;our dear string 
len equ $ - msg ;length of our dear string 

C'est la section de données, il décrit plusieurs variables que nous avons utilisées dans notre programme.

+0

réponse la plus utile pour l'instant. merci beaucoup pour votre temps. – Jeremy