2013-03-24 11 views
8

Da MS-DOS, conosco il richiamo di sistema tramite gli interrupt. Nei vecchi giornali, ho visto il riferimento a int 80h per richiamare le funzioni di sistema su Linux. Da un po 'di tempo ormai, so che lo int 80h è deprecato a favore dell'istruzione syscall. Ma non riesco a farlo funzionare sulla mia macchina a 32 bit.Syscall o sysenter su 32 bit Linux?

La domanda

è l'istruzione syscall per essere utilizzato solo su 64 bit piattaforma? Non 32 bit Linux utilizza syscall?

Un test campione

Nei miei 32 bit di Linux (Ubuntu Precise), questo programma termina con un core dump:

global _start 

_start: 
     mov  eax, 4    ; 4 is write 
     mov  ebx, 1    ; 1 is stdout 
     mov  ecx, message   ; address of string 
     mov  edx, length   ; number of bytes 
     syscall 

     mov  eax, 1    ; 1 is exit 
     xor  ebx, ebx    ; return code 0 
     syscall 

message: 
     db 10,"Hello, World",10,10 
length equ $ - message 

Ho provato con sysenter invece di syscall, ma si blocca il stessa strada.

+0

possibile duplicato di [Cosa è meglio "int 0x80" o "syscall"?] (http://stackoverflow.com/questions/12806584/what -is-better-int-0x80-o-syscall) – Michael

+1

C'è davvero qualcosa di correlato, [qui] (http://stackoverflow.com/a/12806910/279335), ma che non risponde alla que bustione. Dice 'syscall' non è disponibile in modalità a 32 bit di CPU Intel, ma l'assemblatore lo ha compilato in modalità a 32 bit; o l'affermazione non è chiara o è sbagliata. Quindi, ottengo un core-dump a causa di un'istruzione illegale, ma questa istruzione è disponibile su tutte le CPU Intel a partire da Pentium II, e la mia è di gran lunga superiore. Ha menzionato 'sysenter', che ho provato con lo stesso risultato. Ad ogni modo, non ho mai visto alcuna menzione di 'sysenter' in Linux ABI, solo' int 80h' o 'syscall'. – Hibou57

+2

Bene, secondo "[System Calls (wiki.osdev.org)] (http://wiki.osdev.org/System_Calls)", 'syscall' è l'equivalente AMD di Intel' sysenter'. Dice "* Sulla CPU Intel, a partire dal Pentium II, è apparsa una nuova coppia di istruzioni sysenter/sysexit. Consente un passaggio più rapido dalla modalità utente alla modalità kernel, limitando il sovraccarico della modalità di modifica. ** Una coppia di istruzioni simile è stata creata da AMD: Syscall/Sysret **. Tuttavia, il comportamento di queste istruzioni è diverso da quello di Intel. * " – Hibou57

risposta

5

Dopo alcune ricerche sul Web, sono arrivato a questo altro argomento su StackOverflow: Linux invoke a system call via sysenter tutorial. Dice che il modo consigliato di richiamare il sistema, non sta né usando int 80hsyscallsysenter, ma linux-gate.so.

Rimane ancora la domanda sull'arresto anomalo e sul core-dump. La mia ipotesi è infine che sebbene le istruzioni o sysenter siano disponibili come istruzione CPU, potrebbe essere il kernel Linux che non imposta correttamente questo "punto di ingresso" quando deciderà che non è veramente utile su una data piattaforma hardware.

Sembra da 32 bit piattaforma, sysenter o syscallpossono essere disponibili, mentre è sempre disponibile, solo su 64 bit piattaforma.

Sebbene ritenga questa risposta la mia domanda, accolgo ancora più materiale, come un riferimento autorevole per la mia ipotesi precedente.

- aggiornamento -

Almeno, ho trovato questo che confermano quanto sopra. Questo non è ancora un riferimento autorevole, ma credo sia abbastanza affidabile.

What is linux-gate.so.1?, dice:

Il modo preferito di invocare una chiamata di sistema è determinata dal kernel al momento del boot, e evidentemente dal box utilizza SYSENTER.

Inoltre, da un'altra fonte, una fonte di assemblaggio campione FASM (ha bisogno di alcune traduzioni se si utilizza NASM), per chiamare una funzione di sistema tramite linux-gate.so: Finding linux-gate.so.1 in Assembly.

+1

Si noti che quando si utilizza sysenter/syscall, la convenzione potrebbe non essere interamente uguale a quella dell'uso di 0x80 int. Per 'sysenter' avrai bisogno di, iirc,' push ecx push edx push ebp mov ebp, esp 'destra prima di 'sysenter' – nos

+1

Si noti che poiché è' determinato dal kernel all'avvio' si ottiene int 80 , sysenter o syscall a seconda delle capacità della CPU. Int 80 funzionerà sempre, ma è lento e sulle nuove CPU funziona solo uno di sysenter o syscall. Non è una scelta che il programma dovrebbe fare, il kernel fa la scelta ottimale per te. –

5

Il Intel manual afferma che syscall non è valido in modalità di compatibilità (32 bit), quindi non deve essere utilizzato dal kernel.

Questo sembra essere un Intel-unica restrizione tuttavia: https://stackoverflow.com/a/29784932/895245 che AMD non ha, ma certamente Linux deve supportare Intel :-)

sysenter sembra essere il modo migliore per farlo oggi come lo è più veloce di int 0x80, ma dovrebbe essere utilizzato indirettamente tramite VDSO come spiegato a How to invoke a system call via sysenter in inline assembly (x86/amd64 linux)?

+1

Qualcuno ha sollevato lo stesso commento sulla domanda iniziale. Ho risposto che l'istruzione è stata compilata dall'assemblatore che ho usato senza nemmeno un avvertimento e l'opcode è stato documentato per 32 bit. Può essere che questo non sia valido nella modalità a 32 bit dell'architettura a 64 bit ... Comunque, come hai detto, nel contesto di Linux, è meglio fare affidamento sul VDSO (ci sono metodi per recuperarlo anche senza Glibc). – Hibou57

+1

@ Hibou57: come da [questo thread di commenti] (http://stackoverflow.com/questions/38063529/x86-32-x86-64-polyglot-machine-code-fragment-that-detects-64bit-mode-at- run-ti/38063530? noredirect = 1 # comment63566180_38063530): è valido solo in modalità 32 bit su CPU AMD. Mi ha sorpreso anche il fatto che si assembla e si disassembri in codice a 32 bit, ma a quanto pare AMD ha introdotto syscall separatamente (e forse prima) dall'architettura AMD64. Le istruzioni di Intel hanno vinto per la modalità a 32 bit (come al solito), ma AMD è diventato lo standard per AMD64. –

Problemi correlati