# 17.8 Disassembled Byte-Code

People do not write byte-code; that job is left to the byte compiler. But we provide a disassembler to satisfy a cat-like curiosity. The disassembler converts the byte-compiled code into human-readable form.

The byte-code interpreter is implemented as a simple stack machine. It pushes values onto a stack of its own, then pops them off to use them in calculations whose results are themselves pushed back on the stack. When a byte-code function returns, it pops a value off the stack and returns it as the value of the function.

In addition to the stack, byte-code functions can use, bind, and set ordinary Lisp variables, by transferring values between variables and the stack.

### `command`disassembleobject \&optional buffer-or-nameâ€‹

This command displays the disassembled code for `object`. In interactive use, or if `buffer-or-name` is `nil` or omitted, the output goes in a buffer named `*Disassemble*`. If `buffer-or-name` is non-`nil`, it must be a buffer or the name of an existing buffer. Then the output goes there, at point, and point is left before the output.

The argument `object` can be a function name, a lambda expression (see Lambda Expressions), or a byte-code object (see Byte-Code Objects). If it is a lambda expression, `disassemble` compiles it and disassembles the resulting compiled code.

Here are two examples of using the `disassemble` function. We have added explanatory comments to help you relate the byte-code to the Lisp source; these do not appear in the output of `disassemble`.

``(defun factorial (integer)  "Compute factorial of an integer."  (if (= 1 integer) 1    (* integer (factorial (1- integer)))))     â‡’ factorial``
``(factorial 4)     â‡’ 24``
``(disassemble 'factorial)     -| byte-code for factorial: doc: Compute factorial of an integer. args: (integer)``
``0   varref   integer      ; Get the value of integer and                          ;   push it onto the stack.1   constant 1            ; Push 1 onto stack.``
``2   eqlsign               ; Pop top two values off stack, compare                          ;   them, and push result onto stack.``
``3   goto-if-nil 1         ; Pop and test top of stack;                          ;   if nil, go to 1, else continue.6   constant 1            ; Push 1 onto top of stack.7   return                ; Return the top element of the stack.``
``8:1 varref   integer      ; Push value of integer onto stack.9   constant factorial    ; Push factorial onto stack.10  varref   integer      ; Push value of integer onto stack.11  sub1                  ; Pop integer, decrement value,                          ;   push new value onto stack.12  call     1            ; Call function factorial using first                          ;   (i.e., top) stack element as argument;                          ;   push returned value onto stack.``
``13 mult                   ; Pop top two values off stack, multiply                          ;   them, and push result onto stack.14 return                 ; Return the top element of the stack.``

The `silly-loop` function is somewhat more complex:

``(defun silly-loop (n)  "Return time before and after N iterations of a loop."  (let ((t1 (current-time-string)))    (while (> (setq n (1- n))              0))    (list t1 (current-time-string))))     â‡’ silly-loop``
``(disassemble 'silly-loop)     -| byte-code for silly-loop: doc: Return time before and after N iterations of a loop. args: (n)``
``0   constant current-time-string  ; Push current-time-string                                  ;   onto top of stack.``
``1   call     0            ; Call current-time-string with no                          ;   argument, push result onto stack.``
``2   varbind  t1           ; Pop stack and bind t1 to popped value.``
``3:1 varref   n            ; Get value of n from the environment                          ;   and push the value on the stack.4   sub1                  ; Subtract 1 from top of stack.``
``5   dup                   ; Duplicate top of stack; i.e., copy the top                          ;   of the stack and push copy onto stack.6   varset   n            ; Pop the top of the stack,                          ;   and bind n to the value.;; (In effect, the sequence dup varset copies the top of the stack;; into the value of n without popping it.)``
``7   constant 0            ; Push 0 onto stack.8   gtr                   ; Pop top two values off stack,                          ;   test if n is greater than 0                          ;   and push result onto stack.``
``9   goto-if-not-nil 1     ; Goto 1 if n > 0                          ;   (this continues the while loop)                          ;   else continue.``
``12  varref   t1           ; Push value of t1 onto stack.13  constant current-time-string  ; Push current-time-string                                  ;   onto the top of the stack.14  call     0            ; Call current-time-string again.``
``15  unbind   1            ; Unbind t1 in local environment.16  list2                 ; Pop top two elements off stack, create a                          ;   list of them, and push it onto stack.17  return                ; Return value of the top of stack.``