2012-03-07 12 views
11

Estoy escribiendo una función en el ensamblaje x86 que debe poder invocarse desde el código c, y me pregunto qué registros debo restaurar antes de volver al llamador. Actualmente solo estoy restaurando esp y ebp, mientras que el valor de retorno está en eax. ¿Hay algún otro registro del que deba preocuparme, o podría dejar todo lo que me complace?¿Qué registros se restauran después de una llamada a función x86 en c?

+1

No hay una regla general: tendrá que consultar la documentación del compilador de C para ver qué espera. –

+0

Estoy bastante seguro de que Jerry tiene razón, y depende de la convención de llamadas; si la memoria funciona, existen diferentes convenciones "estándar" en Windows, Posix, etc. ¿Qué compilador estás usando? –

+0

gcc. Encontré esta búsqueda en http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Conventions (ver secuencia de salida), pero no dice nada sobre los registros, solo que deberían ser restaurados a un estado esperado por la persona que llama. – bobbaluba

Respuesta

9

El uso de Microsoft's 32 bit ABI, EAX, EDX y ECX son registros de rayones, todo lo demás debe conservarse.

para x64 en Windows, Microsoft says sólo es necesario para restaurar RBX, RBP, RDI, RSI, R12, R13, R14 y R15.

para x64 bajo cualquier cosa que siga System V & AMD64 (see figure 3.4), su RBP, RBX, RSP, R12, R13, R14 y R15 (que parece raro porque el núcleo utiliza un conjunto de registros y el código de espacio de usuario utiliza otro conjunto, esto se establece en el apéndice A de la documentación de ABI).

6
32-bit: EBX, ESI, EDI, EBP 
64-bit Windows: RBX, RSI, RDI, RBP, R12-R15, XMM6-XMM15 
64-bit Linux,BSD,Mac: RBX, RBP, R12-R15 

Para más detalles ver "Software optimization resources" por Agner Fog. Las convenciones de llamada se describen en this pdf.

+0

No olvide RSP =) –

+0

@StephenCanon, y EIP/RIP :) –

+0

ya sabes, iba a señalar eso también, pero la instrucción 'ret' se ocupa del puntero de instrucción para usted. –

1

si no está seguro de la situación de los registros, estas instrucciones a continuación podrían salvar el día fácilmente.

PUSHA/PUSHAD -- Push all General Registers
POPA/POPAD -- Pop all General Registers

Estas instrucciones empujan y pop el propósito general y los registros SI/ESI, DI/EDI en cierto orden.

El orden para la instrucción PUSHA/PUSHAD es el siguiente.

Opcode Instruction Clocks Description 

60  PUSHA  18  Push AX, CX, DX, BX, original SP, BP, SI, and DI 
60  PUSHAD  18  Push EAX, ECX, EDX, EBX, original ESP, EBP ESI, and EDI 

Y el orden para la instrucción POPA/POPAD es el siguiente. (en orden inverso)

Opcode Instruction Clocks Description 

61  POPA   24  Pop DI, SI, BP, SP, BX, DX, CX, and AX 
61  POPAD   24  Pop EDI, ESI, EBP, ESP(***),EBX, EDX, ECX, and EAX 

*** El valor de ESP se descarta en lugar de cargarse en ESP.

+1

Las instrucciones 'POPA' y' POPAD' ¡en realidad no muestran el registro (E) SP! También corrija un error en 'POPAD': olvidó el registro EBX. Además, está diciendo erróneamente que estas instrucciones tocan los * registros del segmento *. –

Cuestiones relacionadas