1     First log! I've spent a couple weeks setting up the
     
2     basic environment. Much of my time has been in the
     
3     excellent tmux man page.
     
4 
     5     The biggest thing has been having a Bash alias that
     
6     starts up my dev environment for the project. That was
     
7     actually a little tricky.
     
8     The key here is the `start-server` command:
     
9 
    10         alias mm='cd /home/dave/meow5 ;
    
11                   tmux start-server \; source-file tmux.cmds'
    
12 
    13     (Newline and indenting just to make it fit in this log.
    
14     Also note the escaped semicolon: that's to separate the
    
15     two tmux commands (start-server and source-file) but not
    
16     have Bash interpret the semicolon as dividing two
    
17     separate shell commands!
    
18 
    19     I also have the barest begiinnings of a meow5.asm file.
    
20     The next tasks are:
    
21 
    22     1. Write the assembly to print "Meow"
    
23     2. Write the assembly to copy #1 five times in memory
    
24        and jmp to it so that we print "MeowMeowMeowMeowMeow"
    
25 
    26     A couple nights later, I'm halfway through that list:
    
27 
    28         ; A single meow
    
29         ; -----------------------------------------------
    
30             mov ebx, STDOUT
    
31             mov ecx, meow              ; str start addr
    
32             mov edx, (meow_end - meow) ; str length
    
33             mov eax, SYS_WRITE
    
34             int 0x80
    
35         end_print_meow:
    
36             mov ebx, 0 ; exit with happy 0
    
37         exit: ; (don't forget to set ebx to exit code)
    
38             mov eax, SYS_EXIT
    
39             int 0x80
    
40 
    41     Which works, of course:
    
42 
    43 $ ./build.sh run
    
44 Meow.
    
45 
    46     Okay, now how about just one simple copy. I'm also getting
    
47     more comfortable with writing simple NASM macros:
    
48 
    49         ; The First Test - Can I copy a meow?
    
50         ; -----------------------------------------------
    
51         %define meow_len (end_print_meow - print_meow)
    
52         %define exit_len (end_exit - happy_exit)
    
53 
    54             ; copy meow printing code
    
55             mov edi, data_segment ; destination
    
56             mov esi, print_meow   ; source
    
57             mov ecx, meow_len     ; bytes to copy
    
58             rep movsb             ; copy!
    
59 
    60             ; copy exit code
    
61             mov edi, (data_segment+meow_len) ; destination
    
62             mov esi, happy_exit   ; source
    
63             mov ecx, exit_len ; len
    
64             rep movsb ; copy ecx bytes
    
65 
    66             ; jump to the copied code!
    
67             jmp data_segment
    
68 
    69     Crossing fingers and...
    
70 
    71 $ ./build.sh run
    
72 Meow.
    
73 Meow.
    
74 
    75     What!? That worked? Wow, first try!
    
76 
    77     I mean, OF COURSE it worked. Why wouldn't it?
    
78 
    79     Okay, so obviously I could copy "meow" five times in
    
80     this brute-force way. But the whole point is to do it
    
81     programatically as if I were really compiling several
    
82     words (functions) together into a larger word.
    
83 
    84     Couple nights later: disscovered the '$' preprocessor
    
85     symbol in NASM for the current address, so using that
    
86     for handier routine length calculations at the very
    
87     end of the routine:
    
88 
    89         print_meow:
    
90             ...
    
91         %assign meow_len ($ - print_meow)
    
92 
    93     Now I'm down to 1 meow, but that's okay. Progress
    
94     is slow and steady and my computing environment keeps
    
95     getting better. I've been reading nasmdoc.txt.
    
96 
    97     I've also been reviewing the basics and learning more
    
98     i386 assembly (basic 32-bit x86) from a great book
    
99     called
   
100 
   101         Programming from the Ground Up
   
102             by Jonathan Bartlett
   
103 
   104     Which, among other things, has helped me understand
   
105     _why_ you might want to choose one of the more
   
106     complicated i386 addressing modes.
   
107 
   108     Okay, next night. Baby steps and a lot of review (like,
   
109     I've gotten a little rusty with GDB too!). Here I'm
   
110     stepping through the simple copy-and-run program.
   
111 
   112     (Note that I edit the GDB sessions here for readability
   
113     and take out a fair amount of typos and redundant stuff
   
114     that I think would detract from understanding.)
   
115 
   116     I've already set register EDI to the first "destination"
   
117     address in my BSS segment where I'll inline ("compile")
   
118     my words (or "functions" or "routines"):
   
119 
   120 (gdb) display/x $edi
   
121 1: /x $edi = 0x804a00c
   
122 
   123     First we copy the meow word:
   
124 
   125 74	    mov esi, print_meow   ; source
   
126 75	    mov ecx, meow_len     ; bytes to copy
   
127 76	    rep movsb             ; copy!
   
128 1: /x $edi = 0x804a022
   
129 
   130     I was going to update my "here" pointer to the address
   
131     right after the copied meow, but I realized that EDI was
   
132     already there (and nothing was going to disturb it), so
   
133     why not just leave it alone and compile the exit word?
   
134     Here goes:
   
135 
   136 80	    mov esi, happy_exit   ; source
   
137 81	    mov ecx, exit_len ; len
   
138 82	    rep movsb ; copy ecx bytes
   
139 1: /x $edi = 0x804a02e
   
140 
   141     Looks good. So EDI now points at the next address after
   
142     the copied exit word.
   
143 
   144     (I probably shouldn't rely on EDI to always point to the
   
145     next destination address for inlined code, thoug. Other
   
146     so-called "string" instructions probably change it. So I
   
147     should probabbly use my "here" pointer like I'd
   
148     planned.)
   
149 
   150     Now if that was copied correctly, we can jump to it and
   
151     it'll print "Meow." as expected:
   
152 
   153 85	    jmp data_segment
   
154 (gdb) s
   
155 0x0804a00c in data_segment ()
   
156 (gdb) c
   
157 Continuing.
   
158 Meow.
   
159 [Inferior 1 (process 1391) exited normally]
   
160 
   161     Baby steps to doing this programatically. The next one
   
162     is creating an inline routine to do the copying:
   
163 
   164         ; inline function!
   
165         ;   input: esi - word start source address
   
166         ;   input: ecx - word length
   
167         inline:
   
168             mov edi, [here] ; destination
   
169             rep movsb
   
170             add edi, ecx    ; update here pointer...
   
171             mov [here], edi ; ...and store it
   
172             ret
   
173 
   174     Now the "here" pointer to the data segment for my
   
175     "compiled" program is handled automatically.
   
176 
   177     Calling this is simple. Here's inlining a copy of Meow.
   
178     The exit one is identical except for the labels:
   
179 
   180         ; inline meow into the program:
   
181         mov esi, print_meow   ; source
   
182         mov ecx, meow_len     ; bytes to copy
   
183         call inline
   
184 
   185     It works:
   
186 
   187 Meow.
   
188 
   189     I think I'll inline five meows in a loop and call this
   
190     initial test a success:
   
191 
   192             ; inline five meows
   
193             mov eax, 5 ; 5 meows
   
194         inline_a_meow:
   
195             mov esi, print_meow   ; source
   
196             mov ecx, meow_len     ; bytes to copy
   
197             call inline
   
198             dec eax
   
199             jnz inline_a_meow
   
200 
   201     Feeling foolishly confident, I'm going to skip the
   
202     debugger and just build and run it this time:
   
203 
   204 dave@cygnus~/meow5$ mrun
   
205 Meow.
   
206 Meow.
   
207 Meow.
   
208 Meow.
   
209 Meow.
   
210 
   211     No way! I can still write a simple loop all on my own. I
   
212     guess this still really is sinking in and I really am
   
213     retaining it. Neat!
   
214 
   215     Well, this has hardly taken any time at all. The vast
   
216     majority of my evenings have been spent setting up this
   
217     laptop's environment to make it as easy as possible to
   
218     hop in and add a little bit each night.
   
219 
   220     The next task, which I'll start in log02.txt, will be to
   
221     store my words with some sort of header so they can be
   
222     looked up by name and so I don't have to manually create
   
223     and name the length calculations for every word in the
   
224     assembly source!