| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Now simulated 'Memory' isn't just a single flat array. Instead it knows
about segments and VMAs.
The code segment will always be first, and the data/heap segment will always
be second. The brk() syscall knows about the data segment.
One nice side-effect is that I no longer need to mess with Memory initialization
regardless of where I place my segments.
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
| |
More calling convention tweaks.
Use EBP to get consistently at parameters and locals.
Always put the first function argument closest to EBP.
|
|
|
|
|
| |
New '--dump' commandline arg to incrementally print trace lines to stderr
as they're emitted.
|
|
|
|
| |
Get the calling convention right, per http://www.cs.virginia.edu/~evans/cs216/guides/x86.html
|
| |
|
| |
|
|
|
|
|
| |
Add the test harness to the crenshaw compiler. Though we aren't calling
it yet. But that's because we aren't actually doing anything useful yet.
|
|
|
|
| |
Back to the Crenshaw compiler. Start by using string literals.
|
|
|
|
| |
Upgrade the test harness for the factorial "app" from ex11.
|
|
|
|
|
|
|
|
| |
New helper: compare a null-terminated string (from argv) with a length-prefixed
string (anywhere else).
As long as ex11 continues to pass we can copy the function and its tests
to other programs.
|
|
|
|
|
|
|
|
|
|
|
|
| |
check_ints_equal now prints a newline after the failure message on failure.
We still don't know how to print a final newline after all the tests have
run, for the common case when all tests pass.
Ideally I could just emit a few instructions to `run_tests`. But I'd also
need to add a variable for the newline to the data segment. Or I need some
literal syntax for newlines in strings. We don't have support for backslash-escapes
yet.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Extract a helper from the factorial unit test: check_ints_equal.
Start of a vocabulary for unit tests.
I *could* also start thinking of supporting multi-file programs, but I'm
going to resist the temptation for now. Copy helpers as necessary, and
allow them to mutate and diverge for a while before we pummel them into
a Procrustean "standard library". Extracting a body of shared code immediately
starts to discourage innovation in the shared code.
|
|
|
|
| |
Include LEA (load effective address) in the SubX subset of x86 ISA.
|
|
|
|
|
|
|
|
|
|
| |
Doesn't de-duplicate in the data segment, though. If you use the literal
"foo" a hundred times in your code segment you're gonna spend a hundred
times the space you need to.
We can now simplify our test harness a bit in the factorial app, but we
still have to put in commandline args to compare with manually. We only
support length-prefixed strings, not null-terminated ones.
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
| |
No automated tests for argv_equal because we need it to run automated tests.
But maybe we should have them anyway.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
One of the more painful things I had to debug with machine code. Tricks
I used can be seen in ex10.subx:
- printing argv[1] in various places
- printing a single 'X' in various places to count how many times we get
to different instructions
- exiting with the current value of EAX in various places
I repeatedly went down the wrong trail in several ways:
- forgetting that the problem lay in native runs, and accidentally switching
to subx runs during debugging.
- forgetting to pass commandline args, because ex10 doesn't check its argv
- writing the wrong comment for an instruction, and then miscalculating
the set of registers that need to be saved.
- forgetting that syscalls clobber EAX.
Debugging native runs is hard, because you have to write non-trivial code
to instrument the binary, and instrumentation can itself be buggy.
When we finally tracked it down, I recognized the problem immediately.
I'd meant to confirm the behavior of opcode 8a against bare metal, and
then forgot.
In any case, opcode 8a was inconsistent with 88. Sloppy.
|
| |
|
|
|
|
| |
subx/examples/ex10 doesn't currently run natively. Grr..
|
|
|
|
|
|
|
|
|
|
|
|
| |
Even more cuddling. We want to keep lines short where the opcode and operands
are self-explanatory.
If there are any implicit registers, etc., we'll continue to do the table
layout.
The first two columns look messy now; let's see how this goes.
Maybe I'll give up on the tabular layout altogether, just string args with
a single space.
|
|
|
|
|
| |
Since we're cuddling jump/call args next to the opcode, we can have longer
labels without messing up the layout!
|
|
|
|
|
|
|
|
|
|
|
|
| |
New example program: ascii null-terminated string comparison
I'd hoped this would be a stepping stone to supporting general ascii comparison,
but we're planning to use size-prefixed rather than null-terminated arrays
everywhere. The only exception is commandline arguments, which will remain
null-terminated to interoperate with Linux.
So I'm going to need separate functions for "compare with argv" and for
general string comparison.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
New example, just to fix in my head how arguments go on the stack.
It's possible I'm still confused about the order callers push args in to
the stack. But even if this violates the calling convention, it should
still run.
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
| |
Get the 'edit' script working again with the 'EE' command in Vim.
|
|
|
|
|
|
|
|
|
| |
All it takes is to code-generate a simple function called 'run_tests' that
calls all functions starting with 'test_' one by one.
I've temporarily switched the factorial app to run as a test. But that's
temporary, because all the code to print '.' vs 'F' needs to get extracted
out into a helper.
|
|
|
|
|
| |
Neither jump nor call instructions support immediates. Drop that.
The only form of absolute addressing relies on rm32.
|
| |
|
| |
|
| |
|
| |
|
| |
|