No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

instructions.c 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #include <stdio.h>
  2. #include "instructions.h"
  3. int EBP = 0;
  4. struct instruction {
  5. char ins;
  6. int arg1;
  7. int arg2;
  8. int arg3;
  9. };
  10. struct instruction instructions[MAX_INSTRUCTIONS_SIZE];
  11. int current_line;
  12. int has_error;
  13. int memory[MAX_MEMORY_SIZE];
  14. int exec(int ip);
  15. int valid_memory_addr(int address);
  16. /***** Public funciton *****/
  17. void asm_init() {
  18. current_line = 0;
  19. has_error = 0;
  20. }
  21. void asm_add_3(char ins, int arg1, int arg2, int arg3) {
  22. if (current_line >= MAX_INSTRUCTIONS_SIZE) {
  23. fprintf(stderr, "ERROR readfile : Too much instructions, please modify value of MAX_INSTRUCTIONS_SIZE.\n");
  24. has_error = 1;
  25. return;
  26. }
  27. // ip are validated at runtime; memory addr are validated here
  28. if (ins == AFC || ins == JPF) {
  29. if (!valid_memory_addr(arg1)) {
  30. fprintf(stderr, "ERROR readfile : INVALID addr at line %d, please verify that addr is in range 0 to MAX_MEMORY_SIZE\n", current_line);
  31. has_error = 1;
  32. return;
  33. }
  34. } else if (ins == JMP) {
  35. // do nothing
  36. } else {
  37. if (!(valid_memory_addr(arg1) && valid_memory_addr(arg2)
  38. && valid_memory_addr(arg3))) {
  39. fprintf(stderr, "ERROR readfile : INVALID addr at line %d, please verify that addr is in range 0 to MAX_MEMORY_SIZE\n", current_line);
  40. has_error = 1;
  41. return;
  42. }
  43. }
  44. // When OK
  45. instructions[current_line].ins = ins;
  46. instructions[current_line].arg1 = arg1;
  47. instructions[current_line].arg2 = arg2;
  48. instructions[current_line].arg3 = arg3;
  49. current_line++;
  50. }
  51. void asm_add_2(char ins, int arg1, int arg2) {
  52. asm_add_3(ins, arg1, arg2, 0);
  53. }
  54. void asm_add_1(char ins, int arg1) {
  55. asm_add_3(ins, arg1, 0, 0);
  56. }
  57. void asm_run() {
  58. int ip = 0;
  59. if (has_error) {
  60. fprintf(stderr, "ERROR run : abandoned due to previous error.\n");
  61. return;
  62. }
  63. printf("INFO run : begin\n");
  64. while (ip >= 0 && ip < current_line) {
  65. // wait for user input
  66. //getchar();
  67. // execution
  68. ip = exec(ip);
  69. }
  70. printf("INFO run : end\n");
  71. }
  72. /***** Private funciton *****/
  73. int valid_memory_addr(int addr) {
  74. return addr >= 0 && addr < MAX_MEMORY_SIZE;
  75. }
  76. int exec(int ip) {
  77. int next_ip = ip + 1;
  78. char ins = instructions[ip].ins;
  79. int arg1 = instructions[ip].arg1;
  80. int arg2 = instructions[ip].arg2;
  81. int arg3 = instructions[ip].arg3;
  82. printf("%d : ", ip);
  83. // execute inst
  84. switch (ins) {
  85. case ADD:
  86. printf("ADD @%d = @%d[%d] + @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  87. memory[arg1] = memory[arg2] + memory[arg3]; break;
  88. case MUL:
  89. printf("MUL @%d = @%d[%d] * @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  90. memory[arg1] = memory[arg2] * memory[arg3]; break;
  91. case SOU:
  92. printf("SOU @%d = @%d[%d] - @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  93. memory[arg1] = memory[arg2] - memory[arg3]; break;
  94. case DIV:
  95. printf("DIV @%d = @%d[%d] / @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  96. memory[arg1] = memory[arg2] / memory[arg3]; break;
  97. case COP:
  98. printf("COP @%d = @%d[%d]\n", arg1, arg2, memory[arg2 + EBP]);
  99. memory[arg1 + EBP] = memory[arg2]; break;
  100. case AFC:
  101. printf("AFC @%d = %d\n", arg1, arg2);
  102. memory[arg1] = arg2; break;
  103. case JMP:
  104. printf("JMP to %d\n", arg1);
  105. next_ip = arg1; break;
  106. case JPF:
  107. printf("JPF cond@%d[%d] to %d\n", arg1, memory[arg1], arg2);
  108. if (memory[arg1] != 0) {
  109. next_ip = arg2;
  110. }
  111. break;
  112. case LT:
  113. printf("LT @%d = @%d[%d] < @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  114. memory[arg1] = memory[arg2] < memory[arg3] ? 1 : 0;
  115. break;
  116. case GT:
  117. printf("GT @%d = @%d[%d] > @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  118. memory[arg1] = memory[arg2] > memory[arg3] ? 1 : 0;
  119. break;
  120. case LTE:
  121. printf("LTE @%d = @%d[%d] <= @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  122. memory[arg1] = memory[arg2] <= memory[arg3] ? 1 : 0;
  123. break;
  124. case GTE:
  125. printf("GTE @%d = @%d[%d] >= @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  126. memory[arg1] = memory[arg2] >= memory[arg3] ? 1 : 0;
  127. break;
  128. case EQ:
  129. printf("EQ @%d = @%d[%d] == @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  130. memory[arg1] = memory[arg2] == memory[arg3] ? 1 : 0;
  131. break;
  132. case NEQ:
  133. printf("NEQ @%d = @%d[%d] != @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  134. memory[arg1] = memory[arg2] != memory[arg3] ? 1 : 0;
  135. break;
  136. case PRI:
  137. printf("PRI @%d[%d]\n", arg1, memory[arg1]);
  138. break;
  139. case AND:
  140. printf("AND @%d = @%d[%d] && @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  141. memory[arg1] = memory[arg2] && memory[arg3] ? 1 : 0;
  142. break;
  143. case OR:
  144. printf("OR @%d = @%d[%d] || @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
  145. memory[arg1] = memory[arg2] || memory[arg3] ? 1 : 0;
  146. break;
  147. case NOT:
  148. printf("OR @%d = ! @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2]);
  149. memory[arg1] = ! memory[arg2] ? 1 : 0;
  150. break;
  151. case LEA:
  152. printf("LEA @%d = %d\n", arg1, arg2 + EBP);
  153. memory[arg1 + EBP] = arg2 + EBP;
  154. break;
  155. case COP_LD:
  156. printf("COP_LD @%d = @%d[%d]\n", arg1, arg2, memory[arg2]);
  157. memory[arg1] = memory[memory[arg2]];
  158. break;
  159. case COP_STR:
  160. printf("COP_STR @%d = @%d[%d]\n", arg1, arg2, memory[arg2]);
  161. memory[arg1] = memory[arg2];
  162. break;
  163. case RET:
  164. printf("RET @%d[%d] \n", arg1, memory[arg1]);
  165. if (EBP != 0){
  166. next_ip = memory[EBP - 2];
  167. EBP = memory[EBP - 1];
  168. }
  169. break;
  170. case CALL:
  171. memory[EBP + arg2 - 1] = EBP;
  172. memory[EBP + arg2 - 2] = next_ip;
  173. next_ip = arg1;
  174. EBP += arg2;
  175. break;
  176. default:
  177. fprintf(stderr, "ERROR run : unknown inst.\n");
  178. }
  179. return next_ip;
  180. }