-
Notifications
You must be signed in to change notification settings - Fork 16
/
runtime.html
1240 lines (1011 loc) · 46.3 KB
/
runtime.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
<head>
<meta charset="UTF-8">
<!-- Remove this line if you use the .htaccess -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<meta name="description" content="Build a simple opearting system">
<title>Runtime Environment // Documentation // eXperimental Operating System</title>
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
<link rel="shortcut icon" type="image/png" href="favicon.png">
<link rel="stylesheet" href="css/style.css">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<!-- Prompt IE 7 users to install Chrome Frame -->
<!--[if lt IE 8]><p class=chromeframe>Your browser is <em>ancient!</em> <a href="http://browsehappy.com/">Upgrade to a different browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">install Google Chrome Frame</a> to experience this site.</p><![endif]-->
<div class="container">
<header id="navtop">
<a href="index.html" class="logo fleft">
<img src="img/logo.png" alt="XOS">
</a>
<nav class="fright">
<ul><li><a href="index.html" >Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="documentation.html" class="navactive">Documentation</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="roadmap.html">Roadmap</a></li></ul>
</ul>
</nav>
</header>
<div class="services-page main grid-wrap">
<header class="grid col-full">
<hr>
<p class="fleft">Runtime Environment</p> <br/><br/>
<!-- <a href="doc/usage.pdf" class="button"> Download as PDF </a> -->
</header>
<aside class="grid col-one-quarter mq2-col-full">
<menu>
<ul>
<li><a href="#navintro" class="sec" >Introduction</a></li>
<li><a href="#navmachineview" class="sec" > Machine view of a process</a></li>
<li><a href="#navmemory" class="subsec" > Memory</a></li>
<li><a href="#navregisters" class="subsec" > Registers</a></li>
<li><a href="#navinstr" class="subsec" > Instructions</a></li>
<li><a href="#navtranslate" class="sec" >Translating APL Programs</a></li>
<li><a href="#navfncalls" class="subsec" >Function calls in APL</a></li>
<li><a href="#navsyscalls" class="subsec" >System calls in APL</a></li>
</ul>
</menu>
</aside>
<section class="grid col-three-quarters mq2-col-full">
<div class="grid-wrap">
<article id="navintro" class="grid col-full">
<h2>Introduction</h2>
<p> Runtime Environment of a process refers to execution environment provided to the process by the operating system. </p>
<p> A user program in execution is termed as a process. User programs are written in APL, which is a high level language. When an APL program is compiled, it generates XSM machine instructions. These machine instructions are unprivileged instructions and will be run in the USER mode (See <a href="xsm-spec.html#navmodes">Privilege Modes</a>). An operating system capable of supporting multiprogramming can provide this view to more than one process concurrently. We'll learn about the view of a process in detail in the further sections. </p>
</article>
<div class="up grid col-one-third" style="float:right">
<a href="#navtop" title="Go back up"> top ↑</a>
</div>
<article id="navmachineview" class="grid col-full">
<h2>Machine view of a process</h2>
<p>
Every user process has a limited view of the machine. Also it accesses only a limited set of registers and memory. It cannot use certain instructions directly. These instructions are called privileged instructions (See <a href="xsm-spec#navinstr">Instructions</a> in XSM). The privileged instructions are accessed by the user program through system calls (see <a href="xos-spec.html#navsyscalls">System Calls</a>).
</p>
</article>
<article id="navmemory" class="grid col-full">
<p> <h4>Memory</h4>
In XOS, a process views memory as a contiguous block with starting address 0. The size of the block is 2048 words. However, XSM allocates memory as pages. Each page has 512 words. This means that a process can have use at most 4 pages. Although the user process views this as contiguous 4 memory pages, OS may allocate it as non-contiguous pages in the physical memory. The contiguous view that a process gets of the memory is called its <b>Logical address space</b>. When this is mapped to the physical memory, it is called its <b>Physical Address Space</b>. Logical addresses are translated to physical addresses by the machine using the <a href="xos-spec.html#navaddr">Address translation</a> scheme of XSM. The process is unaware of the existence of a physical address space and the address translation mechanism is hidden from it.
</p>
<p><img src="doc/prostruct1.png"></p>
<p>
Of the 4 pages that the process uses, the first 3 pages are used for storing the code of the program and the 4th page (address 1536 - 2047) is used as the stack of the process. <b>Stack</b> of a process is a data structure for saving runtime variables and function call arguments of the process. Return value of a function is also passed through the stack. Read about stack in <a href="#navfncalls" class="subsec" >function calls in APL</a>.
</p>
</article>
<article id="navregisters" class="grid col-full">
<p><h4>Registers</h4>
Although XSM has 34 registers, including program registers, kernel registers, temporary registers and special purpose registers, a particular user process has access to a limited set of registers (See <a href="xsm-spec.html#navregset">Register Set</a> in XSM). The register set that is visible to a user process includes only the Program Registers (R0 - R7), SP, BP and IP. Out of which, IP cannot be read / modified. The SP or Stack Pointer points to the address of the top of the stack. BP will be used in function calls. Read about stack in <a href="#navfncalls" class="subsec" >function calls in APL</a>. </p>
<p>IP points to the address of the next instruction to be executed within the code. </p>
</article>
<article id="navinstr" class="grid col-full">
<p> <h4>Instructions</h4>
XSM provides a set of unprivileged instructions. Only these instructions are available to the user program. The user program written in a high level language like APL will compile to only unprivileged instructions. The unprivileged instructions are <tt>MOV</tt>, Arithmetic Instructions, Logic Instructions, Stack Instructions (<tt>PUSH</tt> and <tt>POP</tt>), Sub-routine instructions, input/output instructions, debug instructions, <tt>END</tt> and <tt>INT</tt> (see <a href="xsm-spec.html#navinstr">Instructions</a> in XSM).
</p>
<br/><br/>
<p><b>NOTE:</b> This limited view is given to the user process by the operating system (XOS). APL is a language which is used to write user programs for XOS. These user programs will run in XOS with a limited machine view allowed for user processes. Hence the translated machine code will use only the limited set of instructions, registers and memory described above. The System Pogrammer's Language (SPL), on the other hand is designed to write system programs and has a complete view of the instructions, registers and memory. </p>
</article>
<div class="up grid col-one-third" style="float:right">
<a href="#navtop" title="Go back up"> top ↑</a>
</div>
<article id="navtranslate" class="grid col-full">
<h2>Translating APL programs</h2>
<p> APL compiler translates an APL program into XSM machine instructions. There are two fundamental aspects about compilers that you must understand. First is how the APL compiler translates a Function Call. Second is how the APL compiler generates instructions for a system call.</p>
</article>
<div class="up grid col-one-third" style="float:right">
<a href="#navtop" title="Go back up"> top ↑</a>
</div>
<article id="navfncalls" class="grid col-full">
<h3>Function Calls</h3>
<p> A function call or a subroutine invocation is done by the machine instruction <tt>CALL</tt> (see <a href="xsm-spec.html#navsubroutine">subroutine instructions</a> in XSM). The stack is used to pass arguments to the function and get back the return value. Stack is necessary for a programming language that supports recursion. This will be explained in detail, later in this page. Note that APL is a language that supports recursion. The stack of the user process stores information about the active subroutines of the program. An active subroutine is one that has been called but is yet to complete execution. Control should be handed back to the point of call after completing the function execution. </p>
<p> The activation record corresponding to an active subroutine (or the active function) is shown below. The bottom position of the activation record is pointed to by the BP, and the top of the stack is by SP. The region between BP an SP within the stack is the activation record of the active function. See the figure below.</p>
<img src="doc/activationrecord.png" style="width:200px" />
<br/><br/>
<p>(<b>NOTE</b> In XOS, stack grows from a lower memory address to a higher memory address. )
</p>
<p> The stack contents when a function call is made is shown in the figure below </p>
<img src="doc/fncall.png" style="width:600px" />
<br/><br/>
<p><h6>A: Actions when a CALLER function invokes a CALLEE function</h6></p>
<ol>
<li> The user registers and arguments are pushed into the stack. (See figure). The registers are pushed to backup its values. The CALLEE can now freely use these registers. Arguments are the inputs to the CALLEE function to perform its actions. The arguments become accessible to the CALLEE from the stack.</li>
<li> An empty space for the return value is pushed into the stack, specified as RETURN VALUE in the above figure. The CALLEE function will store the return value in this space after it is computed. The CALLER will access this return value from the stack after return from the CALLEE.</li>
<li> The <tt>CALL</tt> instruction will push the address of IP into the stack, specified as <tt>RETURN ADDRESS</tt> . This is because the <tt>CALL</tt> instruction changes IP to the address of the CALLEE's starting instruction. After the CALLEE performs its actions it must return back to the point after the function call. Hence the current IP must be backed up</li>
</ol>
<p> APL generates instructions for doing steps 1 and 2. It also generates the machine instruction <tt>CALL</tt> which does step 3.</p>
<!--<p> The activation record for a CALLER function contains its local variables, the arguments it passes to the CALLEE function, the RETURN VALUE and the RETURN ADDRESS. Stack allocation of local variables will be discussed in more detail later.</p> -->
<p><h6>B: Actions upon entry into the CALLEE function</h6></p>
<p> The <tt>CALL</tt> instruction passes control to the starting instruction of the CALLEE function. The first few instructions generated by APL compiler for the CALLEE function does the following actions</p>
<ol>
<li><p>Push the current value of <b>BP</b> to the stack. The base of the activation record of the current function is identified by BP. When the CALLEE function is invoked, BP needs to be changed to the base of activation record of the CALLEE function. Hence, the old value of BP corresponding to the CALLER function must be backed up in the stack so that it can be recovered when control returns back to the CALLER function after completion of CALLEE. </li></p>
<li><p>BP is changed to the value of SP. This is because, the activation record of the CALLEE starts at this point. The CALLEE is the current function and BP must point to the starting point of its activation record. As long as the CALLEE function does not call another function, or does not return back to the CALLER, BP will not change. The region in the stack above this BP till SP will be its activation record. As SP can change during execution, the activation record also varies during execution of the function. </li></p>
</ol>
<p><h6>C: Internal stack operations by the CALLEE function</h6></p>
<p>The local variables declared in the CALLEE program has to be allocated memory. This is done in the stack. Each local variable will be allocated a word in the stack. The Stack Pointer will be updated accordingly. APL compiler will generate machine instructions to do this, when local variables are declared. During runtime of the CALLEE, this space may be modified when local variables are assigned values. The region between SP and BP is known as the activation record of the CALLEE function.</p>
<p><h6>D: Actions in the CALLEE function during return</h6></p>
Upon completion, the CALLEE function must return back to the CALLER. This is done using the APL statement, <tt>return;</tt> which translates to the <tt>RET</tt> machine instruciton. The steps done are given below in detail:
<ol>
<li> The function stores the return value computed in the RETURN VALUE field of the activation record of the CALLER function.</li>
<li> All the local variables of the function are popped from the stack as they are no longer required.</li>
<li> <b>OLD BP</b> is popped out from the stack. <b>BP</b> is set to <b>OLD BP. </b>.
</li>
<li> Then the <tt>RET</tt> instruction is generated by the APL. The <tt>RET</tt> instruction sets the IP to the value on top of the stack. Now the top of the stack points to the top of the activation record of the CALLER function. This value, specified as <b>RETURN ADDRESS</b> was pushed by the CALL instruction. When IP is set to this value, it passes control to the instruction after the <tt>CALL</tt> instruction (that invoked the CALLEE) in the CALLER function.</li>
</ol>
<p><h6>E: Actions in the CALLER function after return</h6></p>
<ol>
<li> The CALLER function obtains the return value from the stack and stores it in a register. It pops out the arguments in its activation record and they are discarded. It also restores the backed up register values, so that the execution of CALLER can resume. Machine instructions to perform the above actions will follow the CALL instruction (which invoked the CALLEE) in the machine code generated by the APL compiler. </li>
</ol>
<p> An example of translating a recursive program to computing the factorial of the number is shown below</p>
<div class="syntax"><pre>decl
integer fact(integer n); // Declaration of fact() function
enddecl
integer fact(integer n) // Definition of recursive function fact()
{
integer f; // Local variable of fact()
if(n==1) then // Checking base case of recursion
f=1;
else
f=n*fact(n-1); // Recursive call to fact(n-1)
endif;
return f; // Value of f is returned to the CALLER function
}
integer main()
{
integer n,result; // Local variables of main()
read(n); // Input is obtained from the user
result=fact(n); // Factorial of 'n' is stored in 'result'
print(result); // The value of 'result' is printed
return 0; // Return from main()
} </pre>
</div>
When the above APL program is compiled, the output file generated will contain machine code. The compiled output is shown below (Comments are given for understanding the code. Instruction size in XSM is <b>two</b> words. Word number is shown on the left for each instruction)
<div class="syntax"><pre>
0: START
2: MOV SP, 1535 // Initialize SP to 1535 (Before Logical Page Number 3)
4: MOV BP, 1535 // Initialize BP to 1535 (Before Logical Page Number 3)
6: JMP 00110 // Jumps to the main() function (word address 110)
// fact() function definition starts here
8: PUSH BP // Old value of BP is pushed
10: MOV BP, SP // BP is changed to SP
12: PUSH R0 // Allocating space for local variable 'f
14: MOV R0, -3 // Argument 1 is obtained at 3rd position below BP.
16: MOV R1, BP // ... it takes more than one XSM instruction
18: ADD R0, R1 // ... to achieve an action
20: MOV R0, [R0] // ...
22: MOV R1, 1 // Checking if condition and branching
24: EQ R0, R1 // ...
26: JZ R0, 00040 // Jumps to 'else' part if condition is false
28: MOV R0, 1 // 'if' condition actions
30: MOV R1, BP // ...
32: ADD R0, R1 // ...
34: MOV R1, 1 // ...
36: MOV [R0], R1 // ...
38: JMP 00088 // Skip 'else' part
40: MOV R0, 1 // 'else ' condition actions begins here
42: MOV R1, BP // ...
44: ADD R0, R1 // ...
46: MOV R1, -3 // ...
48: MOV R2, BP // ...
50: ADD R1, R2 // ...
52: MOV R1, [R1] // ...
54: PUSH R1 // ... Backing up registers (only R1, R0 used)
56: PUSH R0 // ... ...
58: MOV R0, -3 // ... Calculating argument 'n-1' for recursive call
60: MOV R1, BP // ... ...
62: ADD R0, R1 // ... ...
64: MOV R0, [R0] // ... ...
66: MOV R1, 1 // ... ...
68: SUB R0, R1 // ... ...
70: PUSH R0 // ... Push argument 'n-1' to stack
72: PUSH R0 // ... Push a space for return value before function call
74: CALL 8 // ... Recursive call to fact(). jumps to address 8
// The following code is executed after return from fact()
76: POP R2 // ... Popping out the RETURN VALUE from the stack
78: POP R3 // ... Popping out the arguments from the stack
80: POP R0 // ... Popping out the backed up registers from the stack
82: POP R1 // ... ...
84: MUL R1, R2 // ... Computing 'f'
86: MOV [R0], R1 // ...
88: MOV R0, 1 // Obtaining the value of 'f'
90: MOV R1, BP // ...
92: ADD R0, R1 // ...
94: MOV R0, [R0] // ...
96: MOV R1, -2 // Storing the return value at BP - 2
98: MOV R2, BP // ...
100: ADD R1, R2 // ...
102: MOV [R1], R0 // ...
104: POP R0 // Popping out local variable
106: POP BP // Popping out OLDBP to BP
108: RET // Return from the function fact()
// main() starts here
110: PUSH BP // Old value of BP is pushed
112: MOV BP,SP // BP is changed to SP
114: PUSH R0 // Allocating space for local variable 'n'
116: PUSH R0 // Allocating space for local variable 'result'
118: MOV R0, 1 // Computing location of 'n' in the stack (BP + 1)
120: MOV R1, BP // ...
122: ADD R0, R1 // ...
124: IN R1 // Reading 'n' from user
126: MOV [R0], R1 // Saving the value of 'n' to the stack
128: MOV R0, 2 // Computing location of 'result' in the stack (BP + 2)
130: MOV R1, BP // ...
132: ADD R0, R1 // ...
134: PUSH R0 // Backing up registers for function call
136: MOV R0, 1 // Computing arguments for function call
138: MOV R1, BP // ...
140: ADD R0, R1 // ...
142: MOV R0, [R0] // ...
144: PUSH R0 // Pushing arguments to stack
146: PUSH R0 // Allocating space for RETURN VALUE
148: CALL 8 // Function call to fact(), jumps to address 8
// The following code is executed after return from fact()
150: POP R1 // Popping out the RETURN VALUE from the stack
152: POP R2 // Popping out the arguments from the stack
154: POP R0 // Popping out backed up registers
156: MOV [R0], R1 // Saving the return value in 'result'
158: MOV R0, 2 // Getting value of 'result'
160: MOV R1, BP // ...
162: ADD R0, R1 // ...
164: MOV R0, [R0] // ...
166: OUT R0 // Printing 'result'
168: MOV R0, 10 // Preparing for exiting
170: PUSH R0 // ...
172: INT 7 // ...
</pre></div>
<p> When the above program is run with value of 'n' as 2 taken from input, the following will be the condition of stack</p>
<a href="doc/fnstack.png" target="blank"><img src="doc/fnstack.png" style="max-width:95%; "/></a>
</article>
<div class="up grid col-one-third" style="float:right">
<a href="#navtop" title="Go back up"> top ↑</a>
</div>
<article id="navsyscalls" class="grid col-full">
<h3>System Calls</h3>
<p> System calls are like built in functions in APL. When APL translates a system call, it generates an INT instruction, which transfers control to an interrupt service routine that contains the system call implementation. The interrupt routine runs in superuser mode. Read about various <a href="apl-spec.html#navsyscalls">system calls</a> available in APL.</p>
<p>(NOTE: This page describes how a system call in a user program is translated by the APL compiler. The actions done by the system call (within the corresponding interrupt routine) is to be programmed in SPL, by the XOS programmer.)</p>
<p> There are three steps in executing a system call. Invoking the system call, performing the system call and returning from the system call. The instructions to do the first and last steps are generated by APL. This page describes how APL does these steps.</p>
<h5>Invoking a system call</h5>
<p>An user process invokes a system call by first pushing the arguments and system call number into the stack and then invoking the <tt> INT </tt> machine instruction corresponding to the system call. A system call in APL compiles to the a set of machine instructions like the one shown below.</p>
<div class="syntax"> <pre>
PUSH <i>Argument_1</i> // Push arguments to the stack
.
.
PUSH <i>Argument_n</i>
PUSH R0 // Push an empty space for RETURN VALUE
PUSH <i>System_Call_No</i> // Push system call number
INT <i>number</i> // Invoke the corresponding INT instruction</div></pre>
<p>(NOTE: The machine code above is in the form of pseudo code.)</p>
<img src="doc/syscallstack1.png" style="width:50%; float:left; margin-right:5%; ">
<p><b>a) Shows the stack operations performed by the user program before <tt>INT</tt> instruction (See machine instructions above) </b>. The arguments are pushed to stack in an order such that last argument comes on top. A push instruction <tt>PUSH R0</tt> is done to put an empty space in the stack for the return value. The system call implementation must ensure that the return value is stored in this space. The system call number is pushed to the stack. The interrupt routine needs this value to identify the system call. </p>
<p>
<b>b) Shows the contents of the stack after the <tt>INT</tt> instruction is executed. </b> The <tt>INT</tt> instruction will push the value of <tt>IP + 2</tt> on to the stack. This value is the address of the instruction after the <tt>INT</tt> instruction in the user program. Each instruction is 2 words, hence IP is incremented by 2. This IP value will be used by interrupt routine to return back from the system call to the next instruction in the calling program. The <tt>INT</tt> instruction changes mode from USER to KERNEL mode and passes control to the Interrupt Routine corresponding to the system call. </p>
<h5> After return from the system call. </h5>
<p> The interrupt routine instruction transfers control back to the user program to the instruction following the <tt>INT</tt> instruction. The following machine instructions are present after the <tt>INT</tt> instruction in the APL compiled machine code given in the previous step. </p>
<div class="syntax"> <pre>
POP <i>System Call Number </i> // Pop and discard system call number
POP <i>RETURN_VALUE</i> // Pop and save the return value
POP <i>Argument_n</i> // Pop and discard arguments
.
.
POP <i>Argument_1</i></div></pre>
<p>(NOTE: The machine code above is in the form of pseudo code. ) </p>
<p> The machine code above pops the values from the stack. The system call number and arguments were inputs to the system call and hence they may be discarded now. The return value which is stored in the stack by the system call is fetched and used by the user program. </p>
</article>
<br/>
<article id="navsyscallstranslate" class="grid col-full">
<br/> <h4>System calls and their translation</h4>
<p>In this section, example APL programs invoking a system call and their translated machine code is shown. The code is commented for better understanding.</p>
</article>
<article id="navsyscallscreate" class="grid col-full">
<h5>Create</h5>
<div style="width:44%; float:left">
<i>Description:</i> Creates a file in the XFS disk<br/>
<i>System Call No</i>: 1 <br/>
<i>Interrupt Routine No</i>: 1 <br/>
<i>Arguments</i>: filename <br/>
<i>Return Value</i>: 0 (Success) or -1 (Failure) </br>
<div class="syntax"><pre>
// <b>APL program to invoke Create</b>
integer main()
{
integer a;
a = Create("File");
return 0;
}</pre>
</div>
</div>
<div class="syntax" style="width:52%; float:right"><pre>
// <b>Compiled XSM machine code</b>
START
MOV SP, 1535 // Initializes SP to 1535
MOV BP, 1535 // Initializes BP to 1535
JMP 00008 // Jump to main() function
// main() function
//================
PUSH BP
MOV BP,SP
PUSH R0 // Space for 'a' in stack
MOV R0, 1
MOV R1, BP
ADD R0, R1 // address of 'a' is in R0
// preparing stack for system call
MOV R1, "File" // Pushing argument filename
PUSH R1 // ...
PUSH R0 // Pushing space for RETURN VALUE
MOV R1, 1 // Pushing system call number = 1
PUSH R1 // ...
// invoking interrupt routine
INT 1 // Transfers control to interrupt 1
// actions after interrupt routine returns
POP R2 // Pop out system call number
POP R1 // Pop out return value
POP R2 // Pop out the argument
MOV [R0], R1 // Saving the return value in 'a'
MOV R0, 10 // Preparing for exit system call
PUSH R0 // ...
INT 7 // Invoking interrupt 7 (exit)</pre></div>
</article>
<article id="navsyscallsopen" class="grid col-full">
<h5>Open</h5>
<div style="width:44%; float:left">
<i>Description:</i> The Open system call is used to open a file present in the XFS disk. <br/>
<i>System Call No</i>: 2 <br/>
<i>Interrupt Routine No</i>: 2 <br/>
<i>Arguments</i>: filename of the file to be opened <br/>
<i>Return Value</i>: Index of open instance in Per-Process Open File table (Success) or -1 (Failure) <br/>
<div class="syntax"><pre>
// <b>APL program to invoke Open</b>
integer main()
{
integer a;
a = Open("File");
return 0;
}</pre>
</div>
</div>
<div class="syntax" style="width:52%; float:right"><pre>
// <b>Compiled XSM machine code</b>
START
MOV SP, 1535 // Initializes SP to 1535
MOV BP, 1535 // Initializes BP to 1535
JMP 00008 // Jump to main() function
// main() function
//================
PUSH BP
MOV BP,SP
PUSH R0 // Space for 'a' in stack
MOV R0, 1
MOV R1, BP
ADD R0, R1 // address of 'a' is in R0
// preparing stack for system call
MOV R1, "File" // Pushing argument filename
PUSH R1 // ...
PUSH R0 // Pushing space for RETURN VALUE
MOV R1, 2 // Pushing system call number = 2
PUSH R1 // ...
// invoking interrupt routine
INT 2 // Transfers control to interrupt 2
// actions after interrupt routine returns
POP R2 // Pop out system call number
POP R1 // Pop out return value
POP R2 // Pop out the argument
MOV [R0], R1 // Saving the return value in 'a'
MOV R0, 10 // Preparing for exit system call
PUSH R0 // ...
INT 7 // Invoking interrupt 7 (exit)</pre></div>
</article>
<article id="navsyscallsclose" class="grid col-full">
<h5>Close</h5>
<div style="width:44%; float:left">
<i>Description</i>: Closes a file opened by the process.<br/>
<i>System Call No</i>: 3 <br/>
<i>Interrupt Routine No</i>: 2 <br/>
<i>Arguments</i>: fileDescriptor <br/>
<i>Return Value</i>: 0 (Success) or -1 (Failure) </br>
<div class="syntax"><pre>
// <b>APL program to invoke Close</b>
integer main()
{
integer a;
a = Close(0);
return 0;
}</pre> </div>
</div>
<div class="syntax" style="width:51%; float:right"><pre>
// <b> Compiled XSM machine code</b>
START
MOV SP, 1535 // Initializes SP to 1535
MOV BP, 1535 // Initializes BP to 1535
JMP 00008 // Jump to main() function
// main() function
//================
PUSH BP
MOV BP,SP
PUSH R0 // Space for 'a' in stack
MOV R0, 1
MOV R1, BP
ADD R0, R1 // address of 'a' is in R0
// preparing stack for system call
MOV R1, 0 // Pushing argument fileDescriptor
PUSH R1 // ...
PUSH R0 // Pushing space for RETURN VALUE
MOV R1, 3 // Pushing system call number = 3
PUSH R1 // ...
// invoking interrupt routine
INT 2 // Transfers control to interrupt 2
// actions after interrupt routine returns
POP R2 // Pop out system call number
POP R1 // Pop out return value
POP R2 // Pop out the argument
MOV [R0], R1 // Saving the return value in 'a'
MOV R0, 10 // Preparing for exit system call
PUSH R0 // ...
INT 7 // Invoking interrupt 7 (exit)</pre></div>
</article>
<article id="navsyscallsdelete" class="grid col-full">
<h5>Delete</h5>
<div style="width:44%; float:left">
<i>Description:</i> Deletes a file in the disk with the filename given as argument. <br/>
<i>System Call No</i>: 4 <br/>
<i>Interrupt Routine No</i>: 1 <br/>
<i>Arguments</i>: filename <br/>
<i>Return Value</i>: 0 (Success) or -1 (Failure) </br>
<div class="syntax"><pre>
// <b>APL program to invoke Delete</b>
integer main()
{
integer a;
a = Delete("File");
return 0;
}</pre></div>
</div>
<div class="syntax" style="width:52%; float:right"><pre>
// <b> Compiled XSM machine code</b>
START
MOV SP, 1535 // Initializes SP to 1535
MOV BP, 1535 // Initializes BP to 1535
JMP 00008 // Jump to main() function
// main() function
//================
PUSH BP
MOV BP,SP
PUSH R0 // Space for 'a' in stack
MOV R0, 1
MOV R1, BP
ADD R0, R1 // address of 'a' is in R0
// preparing stack for system call
MOV R1, "File" // Pushing argument filename
PUSH R1 // ...
PUSH R0 // Pushing space for RETURN VALUE
MOV R1, 4 // Pushing system call number = 4
PUSH R1 // ...
// invoking interrupt routine
INT 1 // Transfers control to interrupt 1
// actions after interrupt routine returns
POP R2 // Pop out system call number
POP R1 // Pop out return value
POP R2 // Pop out the argument
MOV [R0], R1 // Saving the return value in 'a'
MOV R0, 10 // Preparing for exit system call
PUSH R0 // ...
INT 7 // Invoking interrupt 7 (exit)</pre></div>
</article>
<article id="navsyscallswrite" class="grid col-full">
<h5>Write</h5>
<div style="width:44%; float:left">
<i>Description:</i> Used to write a single word to a file opened by the process<br/>
<i>System Call No</i>: 5 <br/>
<i>Interrupt Routine No</i>: 4 <br/>
<i>Arguments</i>: 1. fileDescriptor, 2. wordToWrite <br/>
<i>Return Value</i>: 0 (Success) or -1 (Failure) </br>
<div class="syntax"><pre>
// <b>APL program to invoke Write</b>
integer main()
{
integer a;
a = Write(0,a);
return 0;
}</pre></div> </div>
<div class="syntax" style="width:52%; float:right"><pre>
// <b> Compiled XSM machine code</b>
START
MOV SP, 1535 // Initializes SP to 1535
MOV BP, 1535 // Initializes BP to 1535
JMP 00008 // Jump to main() function
// main() function
//================
PUSH BP
MOV BP,SP
PUSH R0 // Space for 'a' in stack
MOV R0, 1
MOV R1, BP
ADD R0, R1 // address of 'a' is in R0
// Preparing for system calls
MOV R1, 0 // Pushing argument 0
PUSH R1 // ...
MOV R1, 1 // Pushing argument a
MOV R2, BP // ...
ADD R1, R2 // ...
MOV R1, [R1] // ...
PUSH R1 // ...
PUSH R0 // Pushing space for RETURN VALUE
MOV R1, 5 // Pushing system call number = 5
PUSH R1 // ...
// invoking interrupt routine
INT 4 // Transfers control to interrupt 4
// actions after interrupt routine returns
POP R2 // Pop out system call number
POP R1 // Pop out return value
POP R2 // Pop out arguments
POP R2 // ...
MOV [R0], R1 // Store the return value in 'a'
MOV R0, 10 // Preparing for exit system call
PUSH R0 // ...
INT 7 // Invoking interrupt 7 (exit)</pre></div>
</article>
<article id="navsyscallsseek" class="grid col-full">
<h5>Seek</h5>
<div style="width:44%; float:left">
<i>Description</i>: Changes the LSEEK position<br/>
<i>System Call No</i>: 6 <br/>
<i>Interrupt Routine No</i>: 3 <br/>
<i>Arguments</i>: 1. fileDescriptor 2. newLseek <br/>
<i>Return Value</i>: 0 (Success) or -1 (Failure) <br/>
<div class="syntax"><pre>
// <b>APL program to invoke Seek</b>
integer main()
{
integer a;
a = Seek(0,10);
return 0;
}</pre></div> </div>
<div class="syntax" style="width:52%; float:right"><pre>
// <b> Compiled XSM machine code</b>
START
MOV SP, 1535 // Initializes SP to 1535
MOV BP, 1535 // Initializes BP to 1535
JMP 00008 // Jump to main() function
// main() function
//================
PUSH BP
MOV BP,SP
PUSH R0 // Space for 'a' in stack
MOV R0, 1
MOV R1, BP
ADD R0, R1 // address of 'a' is in R0
// Preparing for system calls
MOV R1, 0 // Pushing argument 0
PUSH R1 // ...
MOV R1, 10 // Pushing argument 10
PUSH R1 // ...
PUSH R0 // Pushing space for RETURN VALUE
MOV R1, 6 // Pushing system call number = 6
PUSH R1 // ...
// invoking interrupt routine
INT 3 // Transfers control to interrupt 3
// actions after interrupt routine returns
POP R2 // Pop out system call number
POP R1 // Pop out return value
POP R2 // Pop out arguments
POP R2 // ...
MOV [R0], R1 // Store the return value in 'a'
MOV R0, 10 // Preparing for exit system call
PUSH R0 // ...
INT 7 // Invoking interrupt 7 (exit) </pre></div>
</article>
<article id="navsyscallsread" class="grid col-full">
<h5>Read</h5>
<div style="width:44%; float:left">
<i>Description</i>: Reads a word from a file to the variable passed as argument. <br/>
<i>System Call No</i>: 7 <br/>
<i>Interrupt Routine No</i>: 3 <br/>
<i>Arguments</i>: 1) fileDescriptor 2) wordRead<br/>
<i>Return Value</i>: 0 (success) and -1 (failure) </br>
<div class="syntax"><pre>
// <b>APL program to invoke Read</b>
integer main()
{
integer a;
string b;
// Word read will be in b
// Assume fileDescriptor=0
a = Read(0,b);
return 0;
}</pre></div> </div>
<div class="syntax" style="width:52%; float:right"><pre>
// <b> Compiled XSM machine code</b>
START
MOV SP, 1535 // Initializes SP to 1535
MOV BP, 1535 // Initializes BP to 1535
JMP 00008 // Jump to main() function
// main() function
//================
PUSH BP
MOV BP,SP
PUSH R0 // Space for 'a' in stack
PUSH R0 // Space for 'b' in stack
MOV R0, 1
MOV R1, BP
ADD R0, R1 // address of 'a' is in R0
// Preparing for system calls
MOV R1, 0 // Pushing argument 0
PUSH R1 // ...
MOV R1, 2 // Pushing argument b
MOV R2, BP // ...
ADD R1, R2 // ...
MOV R1, [R1] // ...
PUSH R1 // ...
PUSH R0 // Pushing space for RETURN VALUE
MOV R1, 7 // Pushing system call number = 5
PUSH R1 // ...
// invoking interrupt routine
INT 3 // Transfers control to interrupt 3
// actions after interrupt routine returns
POP R2 // Pop out system call number
MOV R1, 2 // Get the location on 'b'
MOV R2, BP // ...
ADD R1, R2 // ...
POP R2 // Pop out the RETURN VALUE
// Argument 'b' was passed as reference.
POP R3 // Pop and save argument to 'b'
MOV [R1], R3 // ...
MOV R1, R2 // Move return value from R2 to R1
POP R2 // Pop out argument 0
MOV [R0], R1 // Store the return value in 'a'
MOV R0, 10 // Preparing for exit system call
PUSH R0 // ...
INT 7 // Invoking interrupt 7 (exit)</pre></div>
</article>
<article id="navsyscallsfork" class="grid col-full">
<h5>Fork</h5>
<div style="width:44%; float:left">
<i>Description</i>: Replicates the process which invoked this system call in the memory. <br/>
<i>System Call No</i>: 8 <br/>
<i>Interrupt Routine No</i>: 5 <br/>
<i>Arguments</i>: None<br/>
<i>Return Value</i>: In the parent process, PID of the process created (success) or -1 (failure). In the child process, -2 <br/>
<div class="syntax"><pre>
// <b>APL program to invoke Fork</b>
integer main()
{
integer a;
a = Fork();
return 0;
}</pre></div> </div>
<div class="syntax" style="width:52%; float:right"><pre>
// <b> Compiled XSM machine code</b>
START
MOV SP, 1535 // Initializes SP to 1535
MOV BP, 1535 // Initializes BP to 1535
JMP 00008 // Jump to main() function
// main() function
//================
PUSH BP
MOV BP,SP
PUSH R0 // Space for 'a' in stack
MOV R0, 1
MOV R1, BP
ADD R0, R1 // address of 'a' is in R0
// Preparing for system calls
PUSH R0 // Pushing space for RETURN VALUE
MOV R1, 8 // Pushing system call number = 5
PUSH R1 // ...
// invoking interrupt routine
INT 5 // Transfers control to interrupt 5
// actions after interrupt routine returns
POP R2 // Pop out system call number
POP R1 // Pop out the RETURN VALUE
MOV [R0], R1 // Store the return value in 'a'
MOV R0, 10 // Preparing for exit system call
PUSH R0 // ...
INT 7 // Invoking interrupt 7 (exit)</pre></div>
</article>
<article id="navsyscallsexec" class="grid col-full">
<h5>Exec</h5>
<div style="width:44%; float:left">
<i>Description:</i> used to load and run a new process from a currently running process. The current process is overwritten by new process i.e. the process data structures and memory of the current process is used by the new process. </br>
<i>System Call No</i>: 9 <br/>
<i>Interrupt Routine No</i>: 6 <br/>
<i>Arguments</i>: filename <br/>
<i>Return Value</i>: 0 (success) and -1 (failure) </br>
<div class="syntax" ><pre>
// <b>APL program to invoke Exec</b>
integer main()
{
integer a;
a = Exec("File");
return 0;
}</pre></div> </div>
<div class="syntax" style="width:52%; float:right"><pre>
// <b> Compiled XSM machine code</b>
START
MOV SP, 1535 // Initializes SP to 1535
MOV BP, 1535 // Initializes BP to 1535
JMP 00008 // Jump to main() function
// main() function
//================
PUSH BP
MOV BP,SP
PUSH R0 // Space for 'a' in stack
MOV R0, 1
MOV R1, BP
ADD R0, R1 // address of 'a' is in R0
// preparing stack for system call
MOV R1, "File" // Pushing argument filename
PUSH R1 // ...
PUSH R0 // Pushing space for RETURN VALUE
MOV R1, 9 // Pushing system call number = 9
PUSH R1 // ...
// invoking interrupt routine
INT 6 // Transfers control to interrupt 6
// actions after interrupt routine returns
POP R2 // Pop out system call number
POP R1 // Pop out return value
POP R2 // Pop out the argument
MOV [R0], R1 // Saving the return value in 'a'
MOV R0, 10 // Preparing for exit system call
PUSH R0 // ...
INT 7 // Invoking interrupt 7 (exit)</pre></div>
</article>
<article id="navsyscallsexit" class="grid col-full">
<h5>Exit</h5>
<div style="width:44%; float:left">
<i>Description</i>: <br/>Terminate the execution of the process which invoked it. Exit removes this process from the memory. If there is only one process, it halts the system.<br/>
<i>System Call No</i>: 10 <br/>
<i>Interrupt Routine No</i>: 7 <br/>
<i>Arguments</i>: None<br/>
<i>Return Value</i>:-1 on failure, exits on success </br>
<div class="syntax" ><pre>
// <b>APL program to invoke Exit</b>
integer main()
{
Exit();
return 0;
}</pre></div> </div>
<div class="syntax" style="width:52%; float:right"><pre>
// <b> Compiled XSM machine code</b>
START
MOV SP, 1535 // Initializes SP to 1535
MOV BP, 1535 // Initializes BP to 1535
JMP 00008 // Jump to main() function
// main() function
//================
PUSH BP
MOV BP,SP
// preparing stack for the system call
MOV R0, 10 // Pushing system call number = 10
PUSH R0 // ...
// invoking interrupt routine
INT 7 // Transfers control to interrupt 7
// Ideally, it should exit this process and stops execution
POP R0 // Executed, only if exit fails.
MOV R0, 10 // Default Exit() call
PUSH R0 // ...
INT 7 // ...</pre></div>
</article>
<article id="navsyscallsgetpid" class="grid col-full">
<h5>Getpid</h5>
<div style="width:44%; float:left">
<i>Description</i>: Gives the ProcessId of the process which invoked this system call. <br/>
<i>System Call No</i>: 11 <br/>
<i>Interrupt Routine No</i>: 6 <br/>
<i>Arguments</i>: None<br/>
<i>Return Value</i>: PID of the process which invoked the system call (success) or -1 (failure). <br/>
<div class="syntax"><pre>
// <b>APL program to invoke Getpid</b>
integer main()
{
integer a;
a = Getpid();
return 0;
}</pre></div> </div>
<div class="syntax" style="width:52%; float:right"><pre>
// <b> Compiled XSM machine code</b>
START
MOV SP, 1535 // Initializes SP to 1535
MOV BP, 1535 // Initializes BP to 1535
JMP 00008 // Jump to main() function
// main() function
//================
PUSH BP
MOV BP,SP
PUSH R0 // Space for 'a' in stack
MOV R0, 1
MOV R1, BP
ADD R0, R1 // address of 'a' is in R0