Stavo eseguendo il debug di un problema irrilevante nel kernel di Linux e ho visto che il processo etcd, gestito dal supervisore, stava ripetutamente colpendo l'eccezione di errore di pagina e ricevendo SIGSEGV.Qual è questo schema nel codice assembly generato dal compilatore go?
ho ottenuto curioso e usato objdump di smontare il programma, e ho trovato le istruzioni amd64 ha provocato l'errore di essere:
89 04 25 00 00 00 00 mov %eax,0x0
Poi ho guardato lo smontaggio di un programma ciao mondo. Ho visto uno schema molto comune nel codice generato dal compilatore go, che si trova alla fine di una funzione, subito dopo lo ret
, c'è un mov
seguito da un jmp
nella funzione. Ad esempio,
0000000000400c00 <main.main>:
400c00: 64 48 8b 0c 25 f0 ff mov %fs:0xfffffffffffffff0,%rcx
400c07: ff ff
...
400c4b: 48 83 7c 24 48 00 cmpq $0x0,0x48(%rsp)
400c51: 74 59 je 400cac <main.main+0xac>
400c53: 48 c7 04 24 c0 fc 47 movq $0x47fcc0,(%rsp)
400c5a: 00
...
400cab: c3 retq
400cac: 89 04 25 00 00 00 00 mov %eax,0x0
400cb3: eb 9e jmp 400c53 <main.main+0x53>
È questo qualche trucco giocato da go? Se sì, come funziona? Sto indovinando a 0x400c51
salta a 0x400cac
, innesca un SIGSEGV
, che viene gestito e quindi l'istruzione successiva salta a 0x400c53
.
'mov% eax, 0x0' non sposta un registro su un immediato. Sposta un registro per l'indirizzo 0 (a meno che non sia stata eseguita una correzione a un certo punto che ha sostituito 0 con qualcos'altro). Se volessi tentare di spostare 'eax' nell'immediato 0 (che non sarebbe stato assemblato) avresti scritto' mov% eax, $ 0' (con un segno di dollaro). – Michael
@ Michael, grazie per la correzione. Mi sono confuso. –
nessun compilatore imposterà un registro a 0 da mov in modalità ottimizzata. Useranno ['xor reg, reg'] (http://stackoverflow.com/q/33666617/995714) –