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?
Respuesta
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).
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.
No olvide RSP =) –
@StephenCanon, y EIP/RIP :) –
ya sabes, iba a señalar eso también, pero la instrucción 'ret' se ocupa del puntero de instrucción para usted. –
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.
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 *. –
- 1. Convención de llamada personalizada X86_64 a C llamada a función
- 2. ¿Por qué se nombran los registros x86 tal como son?
- 3. ¿cómo se interpreta la definición de una función después de su uso en una llamada a función?
- 4. x86 Montaje: antes de realizar una llamada al sistema en Linux ¿Debería guardar todos los registros?
- 5. Anular una llamada de función en C
- 6. GL_OUT_OF_MEMORY después de una llamada a glDrawArrays. ¿Por qué?
- 7. Convención de llamada ARM a C, registros NEON para guardar
- 8. Función de llamada Ajax después del éxito
- 9. puntero después de la llamada a la función
- 10. función de llamada después de .load (Jquery)
- 11. C: conversión de tipo cuando se pasa un argumento en una llamada a la función
- 12. x86 jnz después de xor?
- 13. ¿Cuál es la función de las instrucciones push/pop usadas en los registros del ensamblaje x86?
- 14. cómo rastrear llamada de función en C?
- 15. ¿Qué significa el anteponer "::" a una llamada de función en C++?
- 16. Llamada a la función c desde Java
- 17. Estado de los registros después del arranque
- 18. ¿Por qué% eax se pone a cero antes de una llamada a printf?
- 19. asíncrona llamada de función para C++
- 20. Llamada C# dll función de C++/CLI
- 21. ¿Usar un constructor en una llamada a función?
- 22. ¿Por qué esta función javascript se ejecuta sin ser llamada?
- 23. ¿Por qué se usan los paréntesis para envolver una llamada a función de JavaScript?
- 24. Función de llamada de Javascript después de window.open
- 25. función asíncrona llamada C++ 0x
- 26. ¿Por qué se debe llamar a glLoadIdentity después de cada llamada a glMatrixMode?
- 27. Función de llamada jQuery después de la carga
- 28. extrayendo un nombre de llamada de función de una llamada a función
- 29. C++ identificador de llamada de función
- 30. JQuery Slider - Función de llamada después de la diapositiva
No hay una regla general: tendrá que consultar la documentación del compilador de C para ver qué espera. –
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? –
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