2016-07-20 15 views
0

Betrachten Sie eine einfache Sprunganweisung (jmp) in Assembly, wobei das Ziel eine vordefinierte Bezeichnung ist.Was wird während einer jmp-Anweisung in der x64-Assembly im Befehlszeiger gespeichert?

jmp destination 

Nach Kip Irvine „Assembly Language für x86-Prozessoren“, wenn die CPU eine bedingungslose Übertragung ausführt, wird der Offset des Ziel in den Befehlszeiger bewegt.

Könnte jemand dies erklären, weil ich dachte, dass die Adresse, zu der wir springen wollen, in den Anweisungszeiger verschoben werden muss?

+2

Was ist der Unterschied zwischen "die Adresse, zu der wir springen wollen" und "der Offset (Adresse) des Ziels"? –

+0

Nun, ist die absolute Adresse im Anweisungszeiger gespeichert oder ein Offset zu einem anderen Wert? – Dennis

+2

IIRC der Wert in IP ist die Adresse des Codesegments + die Adresse des JMP-Labels. Dies ist immer der Fall. In unserer Zeit könnte dies bereits automatisch geschehen, aber früher bedeutet dies: Adresse, wo das Codesegement + Adresse des JMP-Labels beginnt (daher das Wort Offset). – icbytes

Antwort

4

fand ich die Passage du sprichst:

4.5.1 JMP Anweisung

Der JMP-Befehl bewirkt, dass eine bedingungslose Übertragung zu einem Ziel, durch ein Codeetikett identifiziert, die durch denen übersetzt Assembler zu einem Offset. Die Syntax ist

JMP Ziel

Wenn die CPU eine bedingungslose Übertragung ausführt, den Offset des Ziels wird in den Befehlszeiger bewegt, wodurch die Ausführung an dem neuen Ort fortzusetzen.

Ihre Verwirrung ist verständlich; das ist schlecht erklärt.


Vor allem, wenn eine Anweisung sagt jmp destination, dann wird es die Befehlszeiger gleich destination gesetzt. Da hast du Recht.

Aber das Befehlsverhalten wird mit der Anweisung Codierung verwechselt.


Instructions des Formulars jmp address codiert relativen Versätze in x86 verwenden. Die Offsets beziehen sich auf die Adresse unmittelbar nach die jmp Anweisung.

Dies kann entweder als EB gefolgt von einem vorzeichenbehafteten Byte-Offset oder E9 gefolgt von einem vorzeichenbehafteten Dword-Offset codiert werden. (Die ganzen Zahlen sind little endian in x86)

Zum Beispiel

00010000: EB 01 CC 90 

Disassembliert zu

loc_10000: 
    jmp loc_10003 ; EB 01 
    int3   ; CC 
loc_10003: 
    nop   ; 90 

Und

00010000: E9 01 00 00 00 CC 90 

Disassembliert zu

loc_10000: 
    jmp loc_10006 ; E9 01 00 00 00 
    int3   ; CC 
loc_10006: 
    nop   ; 90 

Beachten Sie, dass dies bedeutet, dass auf die gleiche Weise geschriebene Anweisungen unterschiedliche Kodierungen haben können, wenn sie sich an verschiedenen Adressen befinden. Zum Beispiel

00010000: EB 02 EB 00 CC EB FD EB FB 

Disassembliert zu

loc_10000: 
    jmp loc_10004 ; EB 02 
    jmp loc_10004 ; EB 00 
loc_10004: 
    int3   ; CC 
    jmp loc_10004 ; EB FD (FD == -3) 
    jmp loc_10004 ; EB FB (FB == -5) 

Randbemerkung: Es gibt verschiedene Formen der jmp Anweisung, aber die Art von dem Sie sprechen nur mit einem relativen Versatz codiert werden.


Wie auch immer, was der Autor sagt, ist, dass für ein Assembler Maschinencode für einen Befehl wie jmp destination zu erzeugen, ist es destination zu einem Byte-Offset gegenüber dem Ende der jmp Anweisung konvertieren. In den meisten Fällen müssen Sie sich jedoch nicht um diesen Vorgang kümmern. Sie können einfach eine Beschriftung in Ihrer Baugruppe definieren und jmp my_label schreiben, und der Assembler kümmert sich um alles für Sie.

+0

Wenn sie dort "Offset" sagen, meinen sie "Offset von der Basis des CS-Segments" (normalerweise 0 außerhalb des 16-Bit-Codes), nicht die relative Verschiebung, die bei der Maschinencodierung verwendet wird. Alle Adressen in x86 werden Offsets genannt, mit Ausnahme von "far pointer", die ein Segment und einen Offset enthalten. z.B. [das 'jmp ptr16: 32'] (http://www.felixcloutier.com/x86/JMP.html) Formular, das eine unmittelbare absolute Adresse hat. –

1

betrachten diese gefälschte Maschine

address: bytes:  comment: 
0x0004  01 20 00  ; jmp destination ; here ip = 0x0004 
0x0007  ?? repeated 0x19 times 
destination: 
0x0020  02   ; hlt ; here ip = 0x0020 

aus dieser Quelle zusammengestellt:

.code 
    org 0x0004 
    jmp destination 
    org 0x0020 
destination: 
    hlt 

So das Symbol destination hier bedeutet absolute Adresse 0x0020 in Abschnitt .code (die ich keine besondere Bedeutung geben, aber Sie können sich vorstellen, was für eine komplexe Konstruktion Sie wollen, zum Beispiel Segmentregister im 16b-Modus von x86).

Dann, wenn die Anweisung mit Code 0x01 jmp "in der Nähe" ist, wird nur Offset dieser absoluten Adresse verwendet, die 0x0020 in diesem einfachen gefälschten Beispiel ist.

Sie können noch andere Varianten von jmp auf Ihrer CPU haben, wie „relative“ 0x03 jmp rel8 fähig -128 zu springen .. + 127 Bytes von der aktuellen ip oder „weit“ 0x04 jmp bank/segment:offset, die ip nicht nur festgelegt würde, aber auch einige Bank-/Segmentmechanismen.

So dass Wort "Offset" auf eine Ära der segment:offset Adressierung zeigt, wo voller Befehlszeiger auf x86 ist cs:ip, nicht nur ip. (cs = code segment)

In modernen 32/64b x86 OS müssen Sie normalerweise cs nicht berühren und arbeiten nur mit Offsets in 32/64b flache virtuelle Speicherzuordnung, dann hat "Adresse" die gleiche Bedeutung wie "Offset der Adresse".

+0

Ich sehe nicht den Wert bei der Schaffung einer falschen Architektur wie oben, um diese Frage zu beantworten, wenn 1) er bereits x86 erwähnt, und 2) absolute direkte Sprünge existieren nicht in x86 – user1354557

+0

@ user1354557 Ich muss gestehen ... Ich kann keinen Kopf in meinen Kopf halten (oder vielleicht nur, dass ich es kann), also muss ich, wenn ich x86 mache, alles nachahmen, was ich in älterem Code sehe, oder die Anleitung noch einmal durchlesen. Ich war dieses Mal faul, also habe ich lieber eine falsche Maschine hinzugefügt, nur um zu erklären, was das Wort "Offset" in diesem Zusammenhang bedeutet. ("JMP m16: 32" ist ziemlich nah dran, außer etwas ganz anderes und indirektes zu sein). – Ped7g