Skip to content

Instantly share code, notes, and snippets.

@ebb
Last active June 6, 2016 20:56
Show Gist options
  • Save ebb/8a197cbd2c3577a478c4c3e935f92abc to your computer and use it in GitHub Desktop.
Save ebb/8a197cbd2c3577a478c4c3e935f92abc to your computer and use it in GitHub Desktop.
Preliminary notes on reading the following Language 84 code:
- "Let" is used to introduce non-recursive functions.
- "Define" is used to introduce recursive functions.
- "For" is often used to write loops but it is actually a general binding
construct. It is similar to the "where" keyword of other languages in
that the value expression appears first and is followed by a binding that
is to be in scope within the value expression.
- "Continue" is always used in tail-position and is always followed by a
recursive call to the containing function. It indicates to the reader and
the compiler that the body of the function must be translated into a
loop.
- All loops in Language 84 are ultimately defined in terms of "Define" and
"Continue".
- There is no variable-assignment in Language 84. Loop state resides in the
parameters of tail-recursive functions and is updated at the point of
recursive call.
And now, here's the factorial function written in terms of recursion and an
accumulator:
Let (factorial n)
For (multiplying 1 2)
Define (multiplying f m)
If (m > n)
f
Continue (multiplying (f * m) (m + 1))
And here's the x86-64 code generated for the loop:
401360: eb 1f jmp 401381 <f1+0x31>
401362: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
401368: 89 de mov %ebx,%esi
40136a: 89 ef mov %ebp,%edi
40136c: e8 8f 17 00 00 callq 402b00 <prim_multiply>
401371: 89 df mov %ebx,%edi
401373: be 02 00 00 00 mov $0x2,%esi
401378: 89 c5 mov %eax,%ebp
40137a: e8 c1 17 00 00 callq 402b40 <prim_add>
40137f: 89 c3 mov %eax,%ebx
401381: 44 89 e6 mov %r12d,%esi
401384: 89 df mov %ebx,%edi
401386: e8 b5 18 00 00 callq 402c40 <prim_greater>
40138b: 3d 21 01 00 00 cmp $0x121,%eax
401390: 75 d6 jne 401368 <f1+0x18>
Notes:
- All local values are kept in registers. f=ebp, m=ebx, n=r12d, eax is the
return value, edi is the first argument to a call, and esi is the second
argument to a call.
- $0x121 is the representation of the true value and $0x2 is the
representation of the integer 1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment