Вот версии setmp и longjmp, которые я написал для небольшого подмножества clib (написано и протестировано в Visual Studio 2008).Код сборки хранится в отдельном файле .asm.
.586
.MODEL FLAT, C ; Flat memory model, C calling conventions.
;.STACK ; Not required for this example.
;.DATA ; Not required for this example.
.code
; Simple version of setjmp (x86-32 bit).
;
; Saves ebp, ebx, edi, esi, esp and eip in that order.
;
setjmp_t proc
push ebp
mov ebp, esp
push edi
mov edi, [ebp+8] ; Pointer to jmpbuf struct.
mov eax, [ebp] ; Save ebp, note we are saving the stored version on the stack.
mov [edi], eax
mov [edi+4], ebx ; Save ebx
mov eax, [ebp-4]
mov [edi+8], eax ; Save edi, note we are saving the stored verion on the stack.
mov [edi+12], esi ; Save esi
mov eax, ebp;
add eax, 8
mov [edi+16], eax ; Save sp, note saving sp pointing to last item on stack just before call to setjmp.
mov eax, [ebp+4]
mov [edi+20], eax ; Save return address (will be used as jump address in longjmp().
xor eax, eax ; return 0;
pop edi
pop ebp
ret
setjmp_t endp
; Simple version of longjmp (x86-32 bit).
;
; Restores ebp, ebx, edi, esi, esp and eip.
;
longjmp_t proc
mov edi, [esp+4] ; Pointer to jmpbuf struct.
mov eax, [esp+8] ; Get return value (value passed to longjmp).
mov ebp, [edi] ; Restore ebp.
mov ebx, [edi+4] ; Restore ebx.
mov esi, [edi+12] ; Restore esi.
mov esp, [edi+16] ; Restore stack pointer.
mov ecx, [edi+20] ; Original return address to setjmp.
mov edi, [edi+8] ; Restore edi, note, done last as we were using edi up to this point.
jmp ecx ; Wing and a prayer...
longjmp_t endp
end
Фрагмент кода AC для его проверки:
extern "C" int setjmp_t( int *p);
extern "C" int longjmp_t( int *p, int n);
jmp_buf test2_buff;
void DoTest2()
{
int x;
x = setjmp_t( test2_buff);
printf( "setjmp_t return - %d\n", x);
switch (x)
{
case 0:
printf( "About to do long jump...\n");
longjmp_t( test2_buff, 99);
break;
default:
printf( "Here becauuse of long jump...\n");
break;
}
printf( "Test2 passed!\n");
}
Обратите внимание, что я использовал объявление из 'setjmp.h' длябуфер, но если вы хотите, вы можете использовать массив целых (минимум 6 целых).