aboutsummaryrefslogtreecommitdiff
path: root/src/lib/libc/setjmp.s
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2016-07-16 01:28:04 +0200
committerAlex Auvolat <alex@adnab.me>2016-07-16 01:28:04 +0200
commit59000174aa50ed6b2d24a71576d15e6a53c5be0c (patch)
tree38e0a7623f1b83c4dabb1fddfc49014e623f6456 /src/lib/libc/setjmp.s
parent32407e728971006ed3d0885e01c22fb66c8adc57 (diff)
downloadkogata-59000174aa50ed6b2d24a71576d15e6a53c5be0c.tar.gz
kogata-59000174aa50ed6b2d24a71576d15e6a53c5be0c.zip
Add stubs for many libc functions, and a few implemenations too
Diffstat (limited to 'src/lib/libc/setjmp.s')
-rw-r--r--src/lib/libc/setjmp.s53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/lib/libc/setjmp.s b/src/lib/libc/setjmp.s
new file mode 100644
index 0000000..164cc5b
--- /dev/null
+++ b/src/lib/libc/setjmp.s
@@ -0,0 +1,53 @@
+[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
+
+ ; Store return address
+ mov eax, [esp]
+ mov [esp+40], eax
+
+ ; return 0
+ xor eax, eax
+ ret
+
+
+[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
+ ret