about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--subx/010vm.cc4
-rw-r--r--subx/019syscalls.cc2
-rw-r--r--subx/020elf.cc7
-rw-r--r--subx/ex5bin0 -> 138 bytes
-rw-r--r--subx/ex5.subx47
5 files changed, 57 insertions, 3 deletions
diff --git a/subx/010vm.cc b/subx/010vm.cc
index 17c4e064..50074114 100644
--- a/subx/010vm.cc
+++ b/subx/010vm.cc
@@ -133,6 +133,7 @@ void run_one_instruction() {
     // End Two-Byte Opcodes Starting With 0f
     default:
       cerr << "unrecognized second opcode after 0f: " << HEXBYTE << NUM(op2) << '\n';
+      DUMP("");
       exit(1);
     }
     break;
@@ -144,16 +145,19 @@ void run_one_instruction() {
       // End Three-Byte Opcodes Starting With f3 0f
       default:
         cerr << "unrecognized third opcode after f3 0f: " << HEXBYTE << NUM(op3) << '\n';
+        DUMP("");
         exit(1);
       }
       break;
     default:
       cerr << "unrecognized second opcode after f3: " << HEXBYTE << NUM(op2) << '\n';
+      DUMP("");
       exit(1);
     }
     break;
   default:
     cerr << "unrecognized opcode: " << HEXBYTE << NUM(op) << '\n';
+    DUMP("");
     exit(1);
   }
 }
diff --git a/subx/019syscalls.cc b/subx/019syscalls.cc
index f9698957..81040d4e 100644
--- a/subx/019syscalls.cc
+++ b/subx/019syscalls.cc
@@ -1,5 +1,6 @@
 :(before "End Single-Byte Opcodes")
 case 0xcd: {  // int imm8 (software interrupt)
+  trace(2, "run") << "syscall" << end();
   uint8_t code = next();
   if (code != 0x80) {
     raise << "Unimplemented interrupt code " << HEXBYTE << code << '\n' << end();
@@ -17,6 +18,7 @@ void process_int80() {
     exit(/*exit code*/Reg[EBX].u);
     break;
   case 3:
+    DUMP("");
     Reg[EAX].i = read(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u);
     break;
   case 4:
diff --git a/subx/020elf.cc b/subx/020elf.cc
index 88de65fd..85bda201 100644
--- a/subx/020elf.cc
+++ b/subx/020elf.cc
@@ -4,6 +4,7 @@
 :(before "End Main")
 assert(argc > 1);
 if (is_equal(argv[1], "run")) {
+  START_TRACING_UNTIL_END_OF_SCOPE;
   assert(argc > 2);
   reset();
   cerr << std::hex;
@@ -59,9 +60,9 @@ void load_elf_contents(uint8_t* elf_contents, size_t size) {
   for (size_t i = 0;  i < e_phnum;  ++i)
     load_segment_from_program_header(elf_contents, size, e_phoff + i*e_phentsize, e_ehsize);
 
-  // TODO: need to set up real stack somewhere
-
-  Reg[ESP].u = Reg[EBP].u = End_of_program;
+  // initialize code and stack
+  Reg[ESP].u = AFTER_STACK;
+  Reg[EBP].u = 0;
   EIP = e_entry;
 }
 
diff --git a/subx/ex5 b/subx/ex5
new file mode 100644
index 00000000..536ddcd6
--- /dev/null
+++ b/subx/ex5
Binary files differdiff --git a/subx/ex5.subx b/subx/ex5.subx
new file mode 100644
index 00000000..f7411939
--- /dev/null
+++ b/subx/ex5.subx
@@ -0,0 +1,47 @@
+## read a character from stdin, save it to a local on the stack, write it to stdout
+
+== 0x08048054  # code segment, after leaving room for ELF header and segment headers
+# opcode        ModR/M                    SIB                   displacement    immediate
+# instruction   mod, reg, Reg/Mem bits    scale, index, base
+# 1-3 bytes     0/1 byte                  0/1 byte              0/1/2/4 bytes   0/1/2/4 bytes
+
+## function main
+  # prolog
+  55                                                                                          # push EBP
+  89            e5                                                                            # copy ESP to EBP
+                # ModR/M: 11 (direct mode) 100 (src ESP) 101 (dest EBP)
+  # allocate x on the stack
+  81            ec                                                              4/imm32       # subtract 4 bytes from ESP
+                # ModR/M: 11 (direct mode) 101 (subtract imm32) 100 (dest EBP)
+
+  ## read(stdin, x, 1)
+  # fd = 0 (stdin)
+  bb                                                                            0/imm32       # copy 0 to EBX
+  # set location to read character to
+  89            e9                                                                            # copy EBP to ECX
+                # ModR/M: 11 (direct mode) 101 (src EBP) 001 (dest ECX)
+  # size = 1 character
+  ba                                                                            1/imm32       # copy 1 to EDX
+  # syscall = read
+  b8                                                                            3/imm32       # copy 3 to EAX
+  # call
+  cd                                                                            128/imm8      # int 80h
+
+  ## write(stdout, x, 1)
+  # fd = 1 (stdout)
+  bb                                                                            1/imm32       # copy 1 to EBX
+  # set location of character to write out
+  89            e9                                                                            # copy EBP to ECX
+                # ModR/M: 11 (direct mode) 101 (src EBP) 001 (dest ECX)
+  # size = 1 character
+  ba                                                                            1/imm32       # copy 1 to EDX
+  # syscall = write
+  b8                                                                            4/imm32       # copy 4 to EAX
+  # call
+  cd                                                                            128/imm8      # int 80h
+
+  ## exit(EBX)
+  b8                                                                            1/imm32       # copy 1 to EAX
+  cd                                                                            128/imm8      # int 80h
+
+# vim:ft=subx:nowrap