2010-11-22 5 views
3

Ich lerne Assembler, und fand einige der folgenden überraschend. Ich im Wesentlichen eine Hallo Welt Code von irgendwo auf derNASM & GDB: erste Anweisung verloren

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 

ich dies mit nasm -f elf -g hellow.asm kompilieren und verknüpfen Internet kopiert, ld hellow.o -o hellow. Wenn ich es jetzt in gdb lade, kann ich den Code auflisten und ihn einfach ausführen. Wenn ich einen Haltepunkt auf die erste mov Anweisung setze, hört das Programm dort nicht auf. Laufen ndisasm (ndisasm -b32 hellow) auf die resultierende Datei, die ich bekommen (der Teil denke ich, ist relevant):

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 

So ist die Anweisung nicht angezeigt.

Ich würde sehr schätzen einen Hinweis, was passiert ist, oder wo zu gehen, um herauszufinden, was passiert ist.

Antwort

1

Der Grund, warum Ihre Anweisung in Ihrer Disassemblierung nicht korrekt angezeigt wird, ist nur ein Ausrichtungsproblem, bei dem es zu zerlegen beginnt und die Anweisungen fallen. Da x86 Befehle mit variabler Länge hat, muss der Disassembler einen Einstiegspunkt kennen. Die korrekte Auflistung ist mehr wie:

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

Das eigentliche Problem mit GDB ist wie es scheint, wahrscheinlich mit, wie Sie den Breakpoint sind Einstellung (plus, kann ich mich nicht erinnern, wenn gdb Drosseln vor dem ersten Befehl auf dem Brechen , Würde ich überprüfen müssen).

+0

In der Tat habe ich diese Anweisungen gefunden, indem Sie einen "Sync-Punkt" zu ndisasm hinzufügen: ndisasm -b32 -s0X80 hellow. Dann wird die Anweisung wie vorgeschlagen dekodiert. Ich nehme an, dass mein binäres Format die Information enthält, dass der Startpunkt bei 80 ist, aber readelf schlägt vor, dass _start bei 08048080 ist, das andere, das dann in 80 endet, scheint mit mir nicht verwandt zu sein. – kasterma

+0

@ kasterma IIRC der Anfang der ausführbaren Datei ist eigentlich Speicheradresse 0x08048000 auf Linux/386 – cthom06

+1

Wenn ich gcc zum Verknüpfen verwenden, bekomme ich eine viel größere ausführbare Datei, aber eine, wo ich einen funktionierenden Haltepunkt auf die erste Anweisung setzen kann. – kasterma