about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-07-16 11:03:08 -0700
committerKartik Agaram <vc@akkartik.com>2018-07-16 11:05:19 -0700
commit0c57224ccff9727fb699994a4c3d5f5c6d6d1881 (patch)
tree50608e44d326f83b12381b41bf0ebdb66f8563f8
parent66050b796e436735c74504b90f915dd6bc66b8b0 (diff)
downloadmu-0c57224ccff9727fb699994a4c3d5f5c6d6d1881.tar.gz
4356 - subx: first program with a data segment
We read() a character from stdin and write() it out to stdout, saving it
to a global variable in between.

ELF binaries are inefficient; you can ask for a low alignment, but the
kernel may not be able to handle it. If you set up a high alignment then
you end up wasting an increasing amount of space in each segment
because of the constraint that the offset bear some relationship with
the loaded address.
-rw-r--r--subx/021translate.cc6
-rwxr-xr-xsubx/ex1bin96 -> 96 bytes
-rwxr-xr-xsubx/ex2bin102 -> 102 bytes
-rwxr-xr-xsubx/ex3bin119 -> 119 bytes
-rwxr-xr-xsubx/ex4bin113 -> 171 bytes
-rw-r--r--subx/ex4.subx27
6 files changed, 24 insertions, 9 deletions
diff --git a/subx/021translate.cc b/subx/021translate.cc
index 4cecb030..2aa4efaa 100644
--- a/subx/021translate.cc
+++ b/subx/021translate.cc
@@ -88,9 +88,9 @@ void dump_elf_header(ostream& out, const program& p) {
     // p_offset
     emit(p_offset);
     // p_vaddr
-    emit(e_entry);
+    emit(p.segments.at(i).start);
     // p_paddr
-    emit(e_entry);
+    emit(p.segments.at(i).start);
     // p_filesz
     uint32_t size = size_of(p.segments.at(i));
     assert(size < SEGMENT_SIZE);
@@ -101,7 +101,7 @@ void dump_elf_header(ostream& out, const program& p) {
     uint32_t p_flags = (i == 0) ? /*r-x*/0x5 : /*rw-*/0x6;  // convention: only first segment is code
     emit(p_flags);
     // p_align
-    uint32_t p_align = 0x4;
+    uint32_t p_align = 0x1000;  // smaller alignments may not be respected by the kernel
     emit(p_align);
 
     // prepare for next segment
diff --git a/subx/ex1 b/subx/ex1
index c4114dfd..f3c9730d 100755
--- a/subx/ex1
+++ b/subx/ex1
Binary files differdiff --git a/subx/ex2 b/subx/ex2
index 38520d38..3bbd979b 100755
--- a/subx/ex2
+++ b/subx/ex2
Binary files differdiff --git a/subx/ex3 b/subx/ex3
index 9c1f9a92..aa209b92 100755
--- a/subx/ex3
+++ b/subx/ex3
Binary files differdiff --git a/subx/ex4 b/subx/ex4
index 21f7118b..15529a9f 100755
--- a/subx/ex4
+++ b/subx/ex4
Binary files differdiff --git a/subx/ex4.subx b/subx/ex4.subx
index 378b1a35..f76f864e 100644
--- a/subx/ex4.subx
+++ b/subx/ex4.subx
@@ -1,15 +1,15 @@
 ## read a character from stdin
 
-== 0x08048054  # code segment, after leaving room for ELF header
+== 0x08048074  # 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
-# 0: e_entry = 0x08048054
-  ## read(1, x, 1)
-  # fd = 1
-  bb                                                                            1/imm32       # copy 1 to EBX
+
+  ## read(stdin, x, 1)
+  # fd = 0 (stdin)
+  bb                                                                            0/imm32       # copy 0 to EBX
   # set location to write to
-  b9                                                                            00 90 04 08   # copy 0x08040000 to ECX
+  b9                                                                            a7 90 04 08   # copy 0x080490a7 to ECX
   # size = 1 character
   ba                                                                            1/imm32       # copy 1 to EDX
   # syscall = read
@@ -17,8 +17,23 @@
   # call
   cd                                                                            128/imm8      # int 80h
 
+  ## write(stdout, x, 1)
+  # fd = 1 (stdout)
+  bb                                                                            1/imm32       # copy 1 to EBX
+  # set location to write to
+  b9                                                                            a7 90 04 08   # copy 0x080490a7 to ECX
+  # size = 1 character
+  ba                                                                            1/imm32       # copy 1 to EDX
+  # syscall = write
+  b8                                                                            4/imm32       # copy 3 to EAX
+  # call
+  cd                                                                            128/imm8      # int 80h
+
   ## exit(EBX)
   b8                                                                            1/imm32       # copy 1 to EAX
   cd                                                                            128/imm8      # int 80h
 
+== 0x080490a7
+00 00 00 00  # space for read() to write to
+
 # vim:ft=subx:nowrap