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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
3
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
4 struct __CbC_env{
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
5 void *ret_p,*env;
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
6 };
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
7
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
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
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
12 return;
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
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
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
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
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
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
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
28 void *env = ({
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
29 struct __CbC_env __CbC_environment;
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
30 env = &__CbC_environment;
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
31 jmp_buf env_buf;
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
32 int retval;
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
33 __CbC_environment.ret_p = &retval;
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
34 __CbC_environment.env = &env_buf;
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
35 // if (setjmp(__CbC_environment.env)){
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
36 /* if (save_env(__CbC_environment)){ */
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
37 /* return retval; */
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
38 /* } */
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
39 asm volatile(
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
40 "movq 0x8(%%rdi), %%r10;" // %r10 = env.env;
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
41 "movq %%rbp, 0x8(%%r10);" // env.env[1] = %rbp; frame pointer
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
42 "movq %%rsp, 0x10(%%r10);" // env.env[2] = %rsp; stack pointer
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
43 "jmp MAIN_AFTER_SET;" // escape from asm
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
44 "MAIN_RET_POINT:;" // return point
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
45 "movq %%rbp, %%rsp;" // fix stack pointer
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
46 "popq %%rbp;" // pop
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
47 "retq;" // return
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
48 "MAIN_AFTER_SET:;" // escape point
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
49 :"+D"(env)::"r10","eax");
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
50 &__CbC_environment;
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
51 });
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
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
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
56 __code return_cs(int val, void* env){
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
57
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
58 asm volatile(
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
59 "movq 0x8(%%rdi), %%r10;" // %r10 = env.env (environment)
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
60 "movq 0x8(%%r10), %%rbp;" // restore frame pointer
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
61 "movq 0x10(%%r10), %%rsp;" // restore stack pointer
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
62 "movl $12, %%eax;" // return value
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
63 "jmp MAIN_RET_POINT;" // goto previous environment
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
64 :"+D"(env)::"r10","eax");
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
65 }
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
66
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
67 __code save_env(void* env){
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
68 }
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
69
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
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
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
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 }