2012-11-12 7 views
7

voglio spingere l'indirizzo a 64 bit su stack come di seguito,spinta sui 64 bit Intel OSX

__asm("pushq $0x1122334455667788"); 

Ma ottengo errore di compilazione e posso solo spingere in modo seguente,

__asm("pushq $0x11223344"); 
Can

qualcuno aiutami a capire il mio errore?

Sono nuovo all'assemblaggio, quindi per favore scusami se la mia domanda sembra stupida.

risposta

16

x86-64 ha alcune peculiarità interessanti, che non sono evidenti, anche se si ha familiarità con 32-bit x86 ...

  1. maggior parte delle istruzioni possono assumere solo un valore immediato a 32 bit, che è sign-extended a 64 bit se usato in un contesto a 64 bit. (. I negozi codifica istruzione solo 32 bit)

    Ciò significa che è possibile utilizzare pushq per valori immedate nell'intervallo 0x0 - 0x7fffffff (cioè positivo firmato valori a 32 bit che sono segno-esteso con 0 bit) o ​​0xffffffff80000000 - 0xffffffffffffffff) (ovvero valori a 32 bit con segno negativo che sono estesi al segno con 1 bit). Ma non puoi usare valori al di fuori di questo intervallo (poiché non possono essere rappresentati nella codifica delle istruzioni).

  2. mov è un caso speciale: esiste una codifica che accetta un operando immediato a 64 bit. Da qui la risposta di Daniel (che è probabilmente la tua migliore scommessa).

  3. Se si in realtà non si vuole danneggiare un registro, è possibile utilizzare più push di valori più piccoli. Tuttavia, la cosa ovvia di spingere due valori a 32 bit non funzionerà. Nel mondo a 64 bit, push funzionerà con un operando a 64 bit (soggetto al punto 1 sopra, se è una costante immediata) o un operando a 16 bit, ma non un operando a 32 bit (anche pushl %eax non è valido). Quindi la cosa migliore che puoi fare è 4 a 16 bit spinge:

    pushw $0x1122; pushw $0x3344; pushw $0x5566; pushw $0x7788

+7

Commento al punto 3 #: 'subq $ 8,% RSP; movl $ 0x55667788, (% rsp); movl $ 11223344, 4 (% rsp) 'potrebbe funzionare anche. – Jester

+3

@Jester: pushl $ 0x55667788; movl $ 11223344, 4 (% rsp)? –

5

Non esiste una singola istruzione in grado di acquisire un valore immediato a 64 bit e di spingerlo nello stack.

9

La soluzione migliore sarebbe quella di fare qualcosa di simile.

movq $0x1122334455667788, %rax 
pushq %rax 

Sostituire %rax con qualsiasi altro 64-bit di registro a trovare adeguata.