Ich möchte die 64-Bit-Adresse auf dem Stack wie folgt drücken,
%Vor%Aber ich bekomme einen Kompilierungsfehler und ich kann den folgenden Weg nur einschieben,
%Vor%Kann mir jemand helfen, meinen Fehler zu verstehen?
Ich bin neu in der Versammlung, also bitte entschuldigt mich, wenn meine Frage dumm klingt.
x86-64 hat einige interessante Macken, die selbst dann nicht offensichtlich sind, wenn Sie mit 32-Bit x86 vertraut sind ...
Die meisten Anweisungen können nur einen unmittelbaren 32-Bit-Wert annehmen, der bei Verwendung in einem 64-Bit-Kontext vorzeichenersetzt auf 64 Bits ist. (Die Befehlscodierung speichert nur 32 Bits.)
Dies bedeutet, dass Sie pushq
für Immedate-Werte im Bereich 0x0
- 0x7fffffff
verwenden können (dh positiv signierte 32-Bit-Werte, die mit 0 Bits vorzeichenerweitert sind) oder 0xffffffff80000000
- 0xffffffffffffffff
) (dh negative vorzeichenbehaftete 32-Bit-Werte, die mit 1 Bit vorzeichenerweitert sind). Sie können jedoch keine Werte außerhalb dieses Bereichs verwenden (da sie nicht in der Befehlskodierung dargestellt werden können).
mov
ist ein Sonderfall: Es gibt eine Codierung, die einen vollständigen 64-Bit-Sofortoperanden benötigt. Daher Daniels Antwort (was wahrscheinlich deine beste Wette ist).
Wenn Sie wirklich ein Register nicht beschädigen wollen, können Sie mehrere Pushs mit kleineren Werten verwenden. Das Offensichtliche von zwei 32-Bit-Werten wird jedoch nicht funktionieren. In der 64-Bit-Welt arbeitet push
mit einem 64-Bit-Operanden (abhängig vom obigen Punkt 1, wenn es sich um eine unmittelbare Konstante handelt) oder einem 16-Bit-Operanden, aber nicht von einem 32-Bit-Operanden (auch pushl %eax
nicht) gültig). Also das Beste, was Sie tun können, ist 4 16-Bit-Pushs:
pushw %code%x1122; pushw %code%x3344; pushw %code%x5566; pushw %code%x7788
Ihre beste Wette wäre, so etwas zu tun.
%Vor% Ersetzen Sie %rax
durch ein anderes 64-Bit-Register, das Sie für angemessen halten.
Es gibt keinen einzelnen Befehl, der einen 64-Bit-Sofortwert aufnehmen und auf den Stapel schieben kann.