From 0c57224ccff9727fb699994a4c3d5f5c6d6d1881 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 16 Jul 2018 11:03:08 -0700 Subject: 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. --- subx/021translate.cc | 6 +++--- subx/ex1 | Bin 96 -> 96 bytes subx/ex2 | Bin 102 -> 102 bytes subx/ex3 | Bin 119 -> 119 bytes subx/ex4 | Bin 113 -> 171 bytes subx/ex4.subx | 27 +++++++++++++++++++++------ 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 Binary files a/subx/ex1 and b/subx/ex1 differ diff --git a/subx/ex2 b/subx/ex2 index 38520d38..3bbd979b 100755 Binary files a/subx/ex2 and b/subx/ex2 differ diff --git a/subx/ex3 b/subx/ex3 index 9c1f9a92..aa209b92 100755 Binary files a/subx/ex3 and b/subx/ex3 differ diff --git a/subx/ex4 b/subx/ex4 index 21f7118b..15529a9f 100755 Binary files a/subx/ex4 and b/subx/ex4 differ diff --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 -- cgit 1.4.1-2-gfad0