2012-07-01 12 views
6

Estaba navegando por la fuente de varias implementaciones setjmp y longjmp y noté que no todos los registros de la CPU se guardan en la estructura jmp_buf. Después de revisar AMD64 ABI, me di cuenta de que solo se guardan los registros guardados en línea.¿Por qué setjmp (3) no guarda todos los registros en AMD64?

No entiendo cómo se puede reanudar por completo el estado de la función cuando solo se han guardado algunos de los registros. Seguramente los registros no guardados deben haber sido golpeados muchas veces una y otra vez hasta que llame al longjmp más tarde?

Todo funciona perfectamente, sin embargo, definitivamente hay algo que no entiendo. Esperaba que alguien pudiera arrojar algo de luz sobre esto.

Gracias!

+0

Hay implementaciones de setjmp que solo guardan el puntero de instrucción/puntero de marco (ver 'libunwind'). Aquellos tienen un setjmp muy rápido pero tiempos de longjmp relativamente lentos y están basados ​​en tablas de cuadros que describen cómo recuperar los otros registros de las ubicaciones guardadas por el que llama y demás. –

+0

¿Dónde podría encontrar la fuente que estabas mirando? – nullpotent

+0

@AljoshaBre Estos son los más legibles que he encontrado hasta ahora: [setjmp] (http://git.etalabs.net/cgi-bin/gitweb.cgi?p=musl;a=blob;f=src/setjmp /x86_64/setjmp.s;h=98f58b8d6551e391f426fc53c81678a03ac89074;hb=HEAD) y [longjmp] (http://git.etalabs.net/cgi-bin/gitweb.cgi?p=musl;a=blob;f=src/ setjmp/x86_64/longjmp.s; h = e175a4b9606bba41eccc8972c22244e533718f0a; hb = HEAD). – haste

Respuesta

4

La función setjmp es una función como cualquier otra y, por lo tanto, se puede suponer que bloquea cualquier registro guardado por la persona que llama. Como tal, no hay necesidad de guardar/restaurar esos registros.

+0

El compilador no tiene la libertad de utilizar ninguno de los registros disponibles como quiera dentro de mi función, i. mi. incluso los registros que no son guardados por 'setjmp'? – haste

+0

No del todo: no puede usar registros guardados por el que llama a través de una llamada a función, porque pueden/serán cambiados. Por ejemplo, considere 'eax' (en x86): el destinatario escribirá un valor de retorno en ese registro, por lo que la persona que llama no puede almacenar nada importante allí a través de una llamada a función. – duskwuff

+1

@haste he falled para esto también. para describirlo con un poco más de detalle: ya que están guardados, y setjmp se considera una función normal, quien llama a setjmp ya guarda esos registros si es necesario, por lo que cuando setjmp regresa a la persona que llama la segunda vez (por longjmp) , la persona que llama habrá almacenado los respectivos registros guardados por la persona que llama antes y podrá restaurarlos. –

Cuestiones relacionadas