Mercurial > hg > CbC > CbC_examples
annotate asmtest2.c @ 22:39ae2535ad2c
setjmp
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 26 Jan 2016 03:16:41 +0900 |
parents | c181f93d4e30 |
children | facab2ddc380 |
rev | line source |
---|---|
17
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 #include <stdio.h> |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 |
22 | 3 |
4 struct __CbC_env{ | |
5 void *ret_p,*env; | |
6 }; | |
7 | |
8 __code factorial(int n,int result,int orig,__code(*print)(int,int,int,__code(*)(),void*), void *exit1env) | |
17
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 { |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 if (n<0) { |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 printf("#0008:err %d!\n",n); |
22 | 12 return; |
13 goto return_cs(0, exit1env); | |
17
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 } |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
15 if (n==0) |
22 | 16 goto (*print)(n,result,orig,print,exit1env); |
17
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17 else { |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18 result *= n; |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
19 n--; |
22 | 20 goto factorial(n,result,orig,print,exit1env); |
17
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
21 } |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 } |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
23 |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
24 int main( int ac, char *av[]) |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
25 { |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
26 int n; |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
27 n = 10; |
22 | 28 void *env = ({ |
29 struct __CbC_env __CbC_environment; | |
30 env = &__CbC_environment; | |
31 jmp_buf env_buf; | |
32 int retval; | |
33 __CbC_environment.ret_p = &retval; | |
34 __CbC_environment.env = &env_buf; | |
35 // if (setjmp(__CbC_environment.env)){ | |
36 /* if (save_env(__CbC_environment)){ */ | |
37 /* return retval; */ | |
38 /* } */ | |
39 asm volatile( | |
40 "movq 0x8(%%rdi), %%r10;" // %r10 = env.env; | |
41 "movq %%rbp, 0x8(%%r10);" // env.env[1] = %rbp; frame pointer | |
42 "movq %%rsp, 0x10(%%r10);" // env.env[2] = %rsp; stack pointer | |
43 "jmp MAIN_AFTER_SET;" // escape from asm | |
44 "MAIN_RET_POINT:;" // return point | |
45 "movq %%rbp, %%rsp;" // fix stack pointer | |
46 "popq %%rbp;" // pop | |
47 "retq;" // return | |
48 "MAIN_AFTER_SET:;" // escape point | |
49 :"+D"(env)::"r10","eax"); | |
50 &__CbC_environment; | |
51 }); | |
52 goto factorial(n,1,n,print,env); | |
17
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
53 return 10; |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
54 } |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
55 |
22 | 56 __code return_cs(int val, void* env){ |
57 | |
58 asm volatile( | |
59 "movq 0x8(%%rdi), %%r10;" // %r10 = env.env (environment) | |
60 "movq 0x8(%%r10), %%rbp;" // restore frame pointer | |
61 "movq 0x10(%%r10), %%rsp;" // restore stack pointer | |
62 "movl $12, %%eax;" // return value | |
63 "jmp MAIN_RET_POINT;" // goto previous environment | |
64 :"+D"(env)::"r10","eax"); | |
65 } | |
66 | |
67 __code save_env(void* env){ | |
68 } | |
69 | |
70 __code print(int n,int result,int orig,__code(*print)(),void*exit1env) | |
17
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
71 { |
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
72 printf("#0032:%d! = %d\n",orig, result); |
22 | 73 goto return_cs(0, exit1env); |
17
a4f44624a253
asm longjmp (can return correct address but return value is wrong)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
74 } |