2010-11-22 31 views
3

J'apprends l'assembleur, et j'ai trouvé ce qui suit de surprenant. Je essentiellement recopié un code mondial de bonjour de quelque part sur InternetNASM & GDB: perdre la première instruction

section .text 
    global _start 

_start: 
    mov edx,len 
    mov ecx,msg 
    mov ebx,1 
    mov eax,4 
    int 0x80  ; interrupt for calling kernel 

    mov eax,1 
    int 0x80 

section .data 

msg db 'Hello, world!',0xa 
len equ $ - msg 

Je compile et établir un lien avec nasm -f elfe -g hellow.asm, ld hellow.o -o hellow. Si je le charge maintenant dans gdb, je peux lister le code et le lancer correctement. Si je mets un point d'arrêt sur la première instruction mov, le programme ne s'arrête pas là. Exécution NDISASM (NDISASM -b32 hellow) sur le fichier résultant je reçois (la partie que je pense est pertinent):

0000007D 0000    add [eax],al 
0000007F 00BA0E000000  add [edx+0xe],bh 
00000085 B9A0900408  mov ecx,0x80490a0 
0000008A BB01000000  mov ebx,0x1 
0000008F B804000000  mov eax,0x4 
00000094 CD80    int 0x80 
00000096 B801000000  mov eax,0x1 
0000009B CD80    int 0x80 

Donc, l'instruction ne semble pas.

J'apprécierais énormément un indice quant à ce qui se passe ou à l'endroit où aller pour découvrir ce qui se passe.

Répondre

1

La raison pour laquelle votre instruction n'apparaît pas correctement dans votre démontage est juste un problème d'alignement de l'endroit où il commence à se désassembler et de la façon dont les instructions tombent. Comme x86 a des instructions de longueur variable, le désassembleur doit connaître un point d'entrée. La liste correcte est plus comme:

00000080 BA0E000000  mov edx,0xe ; I think 
00000085 B9A0900408  mov ecx,0x80490a0 
... 

Le vrai problème est avec gdb il semble, probablement la façon dont vous définissez le point d'arrêt (plus, je ne me souviens pas si gdb selfs sur la rupture avant la première instruction , Je devrais vérifier).

+0

En effet, j'ai trouvé ces instructions en ajoutant un "point de synchronisation" à ndisasm: ndisasm -b32 -s0X80 hellow. Ensuite, l'instruction est décodée comme vous le suggérez. Je suppose que mon format binaire contient l'information que le point de départ est à 80, cependant readelf suggère que _start est à 08048080, lequel autre finissant en 80 semble sans rapport avec moi. – kasterma

+0

@kasterma IIRC le début de l'exécutable est en fait l'adresse mémoire 0x08048000 sur linux/386 – cthom06

+1

Si j'utilise gcc pour la liaison, j'obtiens un exécutable beaucoup plus grand, mais où je peux mettre un point d'arrêt fonctionnel sur la première instruction. – kasterma