Skip to content

Commit 036170a

Browse files
authored
Merge pull request #142 from cmsc430/improve-hustle-notes
Fix hustle notes to reflect cdr first layout of pairs.
2 parents 290dd39 + e628c18 commit 036170a

File tree

1 file changed

+33
-10
lines changed

1 file changed

+33
-10
lines changed

www/notes/hustle.scrbl

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ the address of the boxes content. Likewise with pairs.
363363
We use a register, @racket['rbx], to hold the address of the next free
364364
memory location in memory. To allocate memory, we simply increment
365365
the content of @racket['rbx] by a multiple of 8. To initialize the
366-
memory, we just write into the memory at that location. To contruct a
366+
memory, we just write into the memory at that location. To construct a
367367
pair or box value, we just tag the unused bits of the address.
368368

369369

@@ -392,28 +392,41 @@ dereferencing the memory:
392392
(Mov 'rax (Offset 'rax 0))) ; load memory into rax
393393
)
394394

395-
Pairs are similar. Suppose we want to make @racket[(cons 3 4)]:
395+
Pairs are similar, only they are represented as tagged pointers to two
396+
words of memory. Suppose we want to make @racket[(cons 3 4)]:
396397

397398
@#reader scribble/comment-reader
398399
(racketblock
399-
(seq (Mov 'rax (value->bits 3))
400-
(Mov (Offset 'rbx 0) 'rax) ; write '3' into address held by rbx
401-
(Mov 'rax (value->bits 4))
402-
(Mov (Offset 'rbx 8) 'rax) ; write '4' into word after address held by rbx
400+
(seq (Mov 'rax (value->bits 4))
401+
(Mov (Offset 'rbx 0) 'rax) ; write '4' into address held by rbx
402+
(Mov 'rax (value->bits 3))
403+
(Mov (Offset 'rbx 8) 'rax) ; write '3' into word after address held by rbx
403404
(Mov 'rax rbx) ; copy pointer into return register
404-
(Or 'rax type-pair) ; tag pointer as a pair
405+
(Or 'rax type-cons) ; tag pointer as a pair
405406
(Add 'rbx 16)) ; advance rbx 2 words
406407
)
407408

409+
This code writes two words of memory and leaves a tagged pointer in
410+
@racket['rax]. It's worth noting that we chose to write the
411+
@racket[cdr] of the pair into the @emph{first} word of memory and the
412+
@racket[car] into the @emph{second}. This may seem like a strange
413+
choice, but how we lay out the memory is in some sense an arbitrary
414+
choice, so long as all our pair operations respect this layout. We
415+
could have just as easily done the @racket[car] first and @racket[cdr]
416+
second. The reason for laying out pairs as we did will make things
417+
slightly more convenient when implementing the @racket[cons] primitive
418+
as we'll see later.
419+
420+
408421
If @racket['rax] holds a pair value, we can project out the elements
409422
by erasing the pair tag, leaving just the address of the pair contents,
410423
then dereferencing either the first or second word of memory:
411424

412425
@#reader scribble/comment-reader
413426
(racketblock
414-
(seq (Xor 'rax type-pair) ; erase the pair tag
415-
(Mov 'rax (Offset 'rax 0)) ; load car into rax
416-
(Mov 'rax (Offset 'rax 8))) ; or... load cdr into rax
427+
(seq (Xor 'rax type-cons) ; erase the pair tag
428+
(Mov 'rax (Offset 'rax 8)) ; load car into rax
429+
(Mov 'rax (Offset 'rax 0))) ; or... load cdr into rax
417430
)
418431

419432
From here, writing the compiler for @racket[box], @racket[unbox],
@@ -469,6 +482,16 @@ one:
469482
(show '(cdr x) '(x))
470483
]
471484

485+
We can now see why we chose to layout pairs with the @racket[cdr]
486+
first and @racket[car] second. Since @racket[cons] is a binary
487+
operation, the expression which produces the @racket[car] value will
488+
be evaluated first and pushed on the stack. Then the expression that
489+
produces the @racket[cdr] value will execute with its result sitting
490+
in @racket[rax]. So at this point it's easiest to write out the
491+
@racket[cdr] since it's already sitting in a register. Once we do
492+
that, we can pop the @racket[car] value into @racket['rax] and write
493+
that. Hence our choice for the layout.
494+
472495
@section[#:tag "hustle-run-time"]{A Run-Time for @this-lang}
473496

474497
First, we extend our runtime system's view of values to include

0 commit comments

Comments
 (0)