summaryrefslogtreecommitdiff
path: root/src/libc/setjmp.asm
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-06-10 21:26:24 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-06-10 21:26:24 +0200
commitd6d1bdfefafff50b7b6d15d218c0a188570be541 (patch)
tree15ee8de727d0be5d126efda146b2879de0a72773 /src/libc/setjmp.asm
parenteea5bf4b859eb56c5772c58ca54937a90a10e7ee (diff)
downloadabaos-d6d1bdfefafff50b7b6d15d218c0a188570be541.tar.gz
abaos-d6d1bdfefafff50b7b6d15d218c0a188570be541.tar.bz2
some big renames into subdirs of aspects
updated README removed size_t in sys/types.h and sys/types.h itself, size_t is in stddef.h
Diffstat (limited to 'src/libc/setjmp.asm')
-rw-r--r--src/libc/setjmp.asm44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/libc/setjmp.asm b/src/libc/setjmp.asm
new file mode 100644
index 0000000..a20a0af
--- /dev/null
+++ b/src/libc/setjmp.asm
@@ -0,0 +1,44 @@
+[bits 32]
+
+global setjmp
+global longjmp
+
+;typedef struct {
+; uint32_t ebx;
+; uint32_t esp;
+; uint32_t ebp;
+; uint32_t esi;
+; uint32_t edi;
+; uint32_t eip;
+;} jmp_buf[1];
+
+; int setjmp(jmp_buf env)
+setjmp:
+ mov eax, [esp+4] ; the adress of the jump buffer
+ mov [eax], ebx ; safe registers
+ mov [eax+4], esp
+ mov [eax+8], ebp
+ mov [eax+12], esi
+ mov [eax+16], edi
+ mov edx, [esp] ; get return address from the stack (pushed here by call)
+ mov [eax+20], edx
+ mov eax, 0 ; indicate that we come from setjmp, not from a longjmp
+ ret
+
+; void longjmp(jmp_buf env, int value);
+longjmp:
+ mov eax, [esp+4] ; the address of the jump buffer
+ mov ecx, [esp+8] ; the return value for setjmp
+ mov ebx, [eax] ; restore registers
+ mov esp, [eax+4]
+ mov ebp, [eax+8]
+ mov esi, [eax+12]
+ mov edi, [eax+16]
+ mov edx, [eax+20] ; get jump address and store it on the stack for 'ret'
+ mov [esp], edx
+ mov eax, ecx ; get return value
+ cmp eax, 0
+ jnz .return ; non zero, ok, return it
+ mov eax, 1 ; setjmp called with 0, not good, return 1
+.return:
+ ret