about summary refs log tree commit diff stats
path: root/subx
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 /subx
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.
Diffstat (limited to 'subx')
-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