diff options
Diffstat (limited to 'src/lib/libc/setjmp.s')
-rw-r--r-- | src/lib/libc/setjmp.s | 75 |
1 files changed, 34 insertions, 41 deletions
diff --git a/src/lib/libc/setjmp.s b/src/lib/libc/setjmp.s index 164cc5b..a9b5f48 100644 --- a/src/lib/libc/setjmp.s +++ b/src/lib/libc/setjmp.s @@ -1,24 +1,18 @@ [GLOBAL setjmp] setjmp: - ; Store general purpose registers - ; (in new stack frame) - mov [esp+4], eax - mov [esp+8], ebx - mov [esp+12], ecx - mov [esp+16], edx - mov [esp+20], edi - mov [esp+24], esi - mov [esp+28], ebp - mov [esp+32], esp - - ; Store flags - pushf - pop eax - mov [esp+36], eax + ; get return address + mov edx, [esp] + ; get address of jmpbuf structure + mov ecx, [esp+4] - ; Store return address - mov eax, [esp] - mov [esp+40], eax + ; Store general purpose registers + mov [ecx], ebx + mov [ecx+4], edx + mov [ecx+8], ebp + mov [ecx+12], esp + mov [ecx+16], esi + mov [ecx+20], edi + mov [ecx+24], eax ; return 0 xor eax, eax @@ -27,27 +21,26 @@ setjmp: [GLOBAL longjmp] longjmp: - ; on previous stack, resume return address - mov eax, [esp+32] - mov ebx, [esp+40] - mov [eax], ebx - - ; resume flags - mov eax, [esp+36] - push eax - popf - - ; load return value in eax - mov eax, [esp+44] - ; resume geneal purpose registers, except eax/esp - mov ebx, [esp+8] - mov ecx, [esp+12] - mov edx, [esp+16] - mov edi, [esp+20] - mov esi, [esp+24] - mov ebp, [esp+28] - - ; resume previous esp - mov esp, [esp+32] - ; return as if we were the setjmp call + ; get address of jmpbuf structure + mov ecx, [esp+4] + ; get retun value + mov eax, [esp+8] + + ; load general purpose registers + ; (edx contains the return address) + mov ebx, [ecx] + mov edx, [ecx+4] + mov ebp, [ecx+8] + mov esp, [ecx+12] + mov esi, [ecx+16] + mov edi, [ecx+20] + + ; make sure return value is nonzero + test eax, eax + jnz _doret + inc eax +_doret: + ; store back return address + mov [esp], edx ret + |