You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
439 lines
21 KiB
HTML
439 lines
21 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<!-- Copyright (C) 1988-2019 Free Software Foundation, Inc.
|
|
|
|
Permission is granted to copy, distribute and/or modify this document
|
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
|
any later version published by the Free Software Foundation; with the
|
|
Invariant Sections being "Free Software" and "Free Software Needs
|
|
Free Documentation", with the Front-Cover Texts being "A GNU Manual,"
|
|
and with the Back-Cover Texts as in (a) below.
|
|
|
|
(a) The FSF's Back-Cover Text is: "You are free to copy and modify
|
|
this GNU Manual. Buying copies from GNU Press supports the FSF in
|
|
developing GNU and promoting software freedom." -->
|
|
<!-- Created by GNU Texinfo 6.4, http://www.gnu.org/software/texinfo/ -->
|
|
<head>
|
|
<title>Bytecode Descriptions (Debugging with GDB)</title>
|
|
|
|
<meta name="description" content="Bytecode Descriptions (Debugging with GDB)">
|
|
<meta name="keywords" content="Bytecode Descriptions (Debugging with GDB)">
|
|
<meta name="resource-type" content="document">
|
|
<meta name="distribution" content="global">
|
|
<meta name="Generator" content="makeinfo">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<link href="index.html#Top" rel="start" title="Top">
|
|
<link href="Concept-Index.html#Concept-Index" rel="index" title="Concept Index">
|
|
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
|
|
<link href="Agent-Expressions.html#Agent-Expressions" rel="up" title="Agent Expressions">
|
|
<link href="Using-Agent-Expressions.html#Using-Agent-Expressions" rel="next" title="Using Agent Expressions">
|
|
<link href="General-Bytecode-Design.html#General-Bytecode-Design" rel="prev" title="General Bytecode Design">
|
|
<style type="text/css">
|
|
<!--
|
|
a.summary-letter {text-decoration: none}
|
|
blockquote.indentedblock {margin-right: 0em}
|
|
blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
|
|
blockquote.smallquotation {font-size: smaller}
|
|
div.display {margin-left: 3.2em}
|
|
div.example {margin-left: 3.2em}
|
|
div.lisp {margin-left: 3.2em}
|
|
div.smalldisplay {margin-left: 3.2em}
|
|
div.smallexample {margin-left: 3.2em}
|
|
div.smalllisp {margin-left: 3.2em}
|
|
kbd {font-style: oblique}
|
|
pre.display {font-family: inherit}
|
|
pre.format {font-family: inherit}
|
|
pre.menu-comment {font-family: serif}
|
|
pre.menu-preformatted {font-family: serif}
|
|
pre.smalldisplay {font-family: inherit; font-size: smaller}
|
|
pre.smallexample {font-size: smaller}
|
|
pre.smallformat {font-family: inherit; font-size: smaller}
|
|
pre.smalllisp {font-size: smaller}
|
|
span.nolinebreak {white-space: nowrap}
|
|
span.roman {font-family: initial; font-weight: normal}
|
|
span.sansserif {font-family: sans-serif; font-weight: normal}
|
|
ul.no-bullet {list-style: none}
|
|
-->
|
|
</style>
|
|
|
|
|
|
</head>
|
|
|
|
<body lang="en">
|
|
<a name="Bytecode-Descriptions"></a>
|
|
<div class="header">
|
|
<p>
|
|
Next: <a href="Using-Agent-Expressions.html#Using-Agent-Expressions" accesskey="n" rel="next">Using Agent Expressions</a>, Previous: <a href="General-Bytecode-Design.html#General-Bytecode-Design" accesskey="p" rel="prev">General Bytecode Design</a>, Up: <a href="Agent-Expressions.html#Agent-Expressions" accesskey="u" rel="up">Agent Expressions</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<hr>
|
|
<a name="Bytecode-Descriptions-1"></a>
|
|
<h3 class="section">F.2 Bytecode Descriptions</h3>
|
|
|
|
<p>Each bytecode description has the following form:
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><code>add</code> (0x02): <var>a</var> <var>b</var> ⇒ <var>a+b</var></dt>
|
|
<dd>
|
|
<p>Pop the top two stack items, <var>a</var> and <var>b</var>, as integers; push
|
|
their sum, as an integer.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>In this example, <code>add</code> is the name of the bytecode, and
|
|
<code>(0x02)</code> is the one-byte value used to encode the bytecode, in
|
|
hexadecimal. The phrase “<var>a</var> <var>b</var> ⇒ <var>a+b</var>” shows
|
|
the stack before and after the bytecode executes. Beforehand, the stack
|
|
must contain at least two values, <var>a</var> and <var>b</var>; since the top of
|
|
the stack is to the right, <var>b</var> is on the top of the stack, and
|
|
<var>a</var> is underneath it. After execution, the bytecode will have
|
|
popped <var>a</var> and <var>b</var> from the stack, and replaced them with a
|
|
single value, <var>a+b</var>. There may be other values on the stack below
|
|
those shown, but the bytecode affects only those shown.
|
|
</p>
|
|
<p>Here is another example:
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><code>const8</code> (0x22) <var>n</var>: ⇒ <var>n</var></dt>
|
|
<dd><p>Push the 8-bit integer constant <var>n</var> on the stack, without sign
|
|
extension.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>In this example, the bytecode <code>const8</code> takes an operand <var>n</var>
|
|
directly from the bytecode stream; the operand follows the <code>const8</code>
|
|
bytecode itself. We write any such operands immediately after the name
|
|
of the bytecode, before the colon, and describe the exact encoding of
|
|
the operand in the bytecode stream in the body of the bytecode
|
|
description.
|
|
</p>
|
|
<p>For the <code>const8</code> bytecode, there are no stack items given before
|
|
the ⇒; this simply means that the bytecode consumes no values
|
|
from the stack. If a bytecode consumes no values, or produces no
|
|
values, the list on either side of the ⇒ may be empty.
|
|
</p>
|
|
<p>If a value is written as <var>a</var>, <var>b</var>, or <var>n</var>, then the bytecode
|
|
treats it as an integer. If a value is written is <var>addr</var>, then the
|
|
bytecode treats it as an address.
|
|
</p>
|
|
<p>We do not fully describe the floating point operations here; although
|
|
this design can be extended in a clean way to handle floating point
|
|
values, they are not of immediate interest to the customer, so we avoid
|
|
describing them, to save time.
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><code>float</code> (0x01): ⇒</dt>
|
|
<dd>
|
|
<p>Prefix for floating-point bytecodes. Not implemented yet.
|
|
</p>
|
|
</dd>
|
|
<dt><code>add</code> (0x02): <var>a</var> <var>b</var> ⇒ <var>a+b</var></dt>
|
|
<dd><p>Pop two integers from the stack, and push their sum, as an integer.
|
|
</p>
|
|
</dd>
|
|
<dt><code>sub</code> (0x03): <var>a</var> <var>b</var> ⇒ <var>a-b</var></dt>
|
|
<dd><p>Pop two integers from the stack, subtract the top value from the
|
|
next-to-top value, and push the difference.
|
|
</p>
|
|
</dd>
|
|
<dt><code>mul</code> (0x04): <var>a</var> <var>b</var> ⇒ <var>a*b</var></dt>
|
|
<dd><p>Pop two integers from the stack, multiply them, and push the product on
|
|
the stack. Note that, when one multiplies two <var>n</var>-bit numbers
|
|
yielding another <var>n</var>-bit number, it is irrelevant whether the
|
|
numbers are signed or not; the results are the same.
|
|
</p>
|
|
</dd>
|
|
<dt><code>div_signed</code> (0x05): <var>a</var> <var>b</var> ⇒ <var>a/b</var></dt>
|
|
<dd><p>Pop two signed integers from the stack; divide the next-to-top value by
|
|
the top value, and push the quotient. If the divisor is zero, terminate
|
|
with an error.
|
|
</p>
|
|
</dd>
|
|
<dt><code>div_unsigned</code> (0x06): <var>a</var> <var>b</var> ⇒ <var>a/b</var></dt>
|
|
<dd><p>Pop two unsigned integers from the stack; divide the next-to-top value
|
|
by the top value, and push the quotient. If the divisor is zero,
|
|
terminate with an error.
|
|
</p>
|
|
</dd>
|
|
<dt><code>rem_signed</code> (0x07): <var>a</var> <var>b</var> ⇒ <var>a modulo b</var></dt>
|
|
<dd><p>Pop two signed integers from the stack; divide the next-to-top value by
|
|
the top value, and push the remainder. If the divisor is zero,
|
|
terminate with an error.
|
|
</p>
|
|
</dd>
|
|
<dt><code>rem_unsigned</code> (0x08): <var>a</var> <var>b</var> ⇒ <var>a modulo b</var></dt>
|
|
<dd><p>Pop two unsigned integers from the stack; divide the next-to-top value
|
|
by the top value, and push the remainder. If the divisor is zero,
|
|
terminate with an error.
|
|
</p>
|
|
</dd>
|
|
<dt><code>lsh</code> (0x09): <var>a</var> <var>b</var> ⇒ <var>a<<b</var></dt>
|
|
<dd><p>Pop two integers from the stack; let <var>a</var> be the next-to-top value,
|
|
and <var>b</var> be the top value. Shift <var>a</var> left by <var>b</var> bits, and
|
|
push the result.
|
|
</p>
|
|
</dd>
|
|
<dt><code>rsh_signed</code> (0x0a): <var>a</var> <var>b</var> ⇒ <code>(signed)</code><var>a>>b</var></dt>
|
|
<dd><p>Pop two integers from the stack; let <var>a</var> be the next-to-top value,
|
|
and <var>b</var> be the top value. Shift <var>a</var> right by <var>b</var> bits,
|
|
inserting copies of the top bit at the high end, and push the result.
|
|
</p>
|
|
</dd>
|
|
<dt><code>rsh_unsigned</code> (0x0b): <var>a</var> <var>b</var> ⇒ <var>a>>b</var></dt>
|
|
<dd><p>Pop two integers from the stack; let <var>a</var> be the next-to-top value,
|
|
and <var>b</var> be the top value. Shift <var>a</var> right by <var>b</var> bits,
|
|
inserting zero bits at the high end, and push the result.
|
|
</p>
|
|
</dd>
|
|
<dt><code>log_not</code> (0x0e): <var>a</var> ⇒ <var>!a</var></dt>
|
|
<dd><p>Pop an integer from the stack; if it is zero, push the value one;
|
|
otherwise, push the value zero.
|
|
</p>
|
|
</dd>
|
|
<dt><code>bit_and</code> (0x0f): <var>a</var> <var>b</var> ⇒ <var>a&b</var></dt>
|
|
<dd><p>Pop two integers from the stack, and push their bitwise <code>and</code>.
|
|
</p>
|
|
</dd>
|
|
<dt><code>bit_or</code> (0x10): <var>a</var> <var>b</var> ⇒ <var>a|b</var></dt>
|
|
<dd><p>Pop two integers from the stack, and push their bitwise <code>or</code>.
|
|
</p>
|
|
</dd>
|
|
<dt><code>bit_xor</code> (0x11): <var>a</var> <var>b</var> ⇒ <var>a^b</var></dt>
|
|
<dd><p>Pop two integers from the stack, and push their bitwise
|
|
exclusive-<code>or</code>.
|
|
</p>
|
|
</dd>
|
|
<dt><code>bit_not</code> (0x12): <var>a</var> ⇒ <var>~a</var></dt>
|
|
<dd><p>Pop an integer from the stack, and push its bitwise complement.
|
|
</p>
|
|
</dd>
|
|
<dt><code>equal</code> (0x13): <var>a</var> <var>b</var> ⇒ <var>a=b</var></dt>
|
|
<dd><p>Pop two integers from the stack; if they are equal, push the value one;
|
|
otherwise, push the value zero.
|
|
</p>
|
|
</dd>
|
|
<dt><code>less_signed</code> (0x14): <var>a</var> <var>b</var> ⇒ <var>a<b</var></dt>
|
|
<dd><p>Pop two signed integers from the stack; if the next-to-top value is less
|
|
than the top value, push the value one; otherwise, push the value zero.
|
|
</p>
|
|
</dd>
|
|
<dt><code>less_unsigned</code> (0x15): <var>a</var> <var>b</var> ⇒ <var>a<b</var></dt>
|
|
<dd><p>Pop two unsigned integers from the stack; if the next-to-top value is less
|
|
than the top value, push the value one; otherwise, push the value zero.
|
|
</p>
|
|
</dd>
|
|
<dt><code>ext</code> (0x16) <var>n</var>: <var>a</var> ⇒ <var>a</var>, sign-extended from <var>n</var> bits</dt>
|
|
<dd><p>Pop an unsigned value from the stack; treating it as an <var>n</var>-bit
|
|
twos-complement value, extend it to full length. This means that all
|
|
bits to the left of bit <var>n-1</var> (where the least significant bit is bit
|
|
0) are set to the value of bit <var>n-1</var>. Note that <var>n</var> may be
|
|
larger than or equal to the width of the stack elements of the bytecode
|
|
engine; in this case, the bytecode should have no effect.
|
|
</p>
|
|
<p>The number of source bits to preserve, <var>n</var>, is encoded as a single
|
|
byte unsigned integer following the <code>ext</code> bytecode.
|
|
</p>
|
|
</dd>
|
|
<dt><code>zero_ext</code> (0x2a) <var>n</var>: <var>a</var> ⇒ <var>a</var>, zero-extended from <var>n</var> bits</dt>
|
|
<dd><p>Pop an unsigned value from the stack; zero all but the bottom <var>n</var>
|
|
bits.
|
|
</p>
|
|
<p>The number of source bits to preserve, <var>n</var>, is encoded as a single
|
|
byte unsigned integer following the <code>zero_ext</code> bytecode.
|
|
</p>
|
|
</dd>
|
|
<dt><code>ref8</code> (0x17): <var>addr</var> ⇒ <var>a</var></dt>
|
|
<dt><code>ref16</code> (0x18): <var>addr</var> ⇒ <var>a</var></dt>
|
|
<dt><code>ref32</code> (0x19): <var>addr</var> ⇒ <var>a</var></dt>
|
|
<dt><code>ref64</code> (0x1a): <var>addr</var> ⇒ <var>a</var></dt>
|
|
<dd><p>Pop an address <var>addr</var> from the stack. For bytecode
|
|
<code>ref</code><var>n</var>, fetch an <var>n</var>-bit value from <var>addr</var>, using the
|
|
natural target endianness. Push the fetched value as an unsigned
|
|
integer.
|
|
</p>
|
|
<p>Note that <var>addr</var> may not be aligned in any particular way; the
|
|
<code>ref<var>n</var></code> bytecodes should operate correctly for any address.
|
|
</p>
|
|
<p>If attempting to access memory at <var>addr</var> would cause a processor
|
|
exception of some sort, terminate with an error.
|
|
</p>
|
|
</dd>
|
|
<dt><code>ref_float</code> (0x1b): <var>addr</var> ⇒ <var>d</var></dt>
|
|
<dt><code>ref_double</code> (0x1c): <var>addr</var> ⇒ <var>d</var></dt>
|
|
<dt><code>ref_long_double</code> (0x1d): <var>addr</var> ⇒ <var>d</var></dt>
|
|
<dt><code>l_to_d</code> (0x1e): <var>a</var> ⇒ <var>d</var></dt>
|
|
<dt><code>d_to_l</code> (0x1f): <var>d</var> ⇒ <var>a</var></dt>
|
|
<dd><p>Not implemented yet.
|
|
</p>
|
|
</dd>
|
|
<dt><code>dup</code> (0x28): <var>a</var> => <var>a</var> <var>a</var></dt>
|
|
<dd><p>Push another copy of the stack’s top element.
|
|
</p>
|
|
</dd>
|
|
<dt><code>swap</code> (0x2b): <var>a</var> <var>b</var> => <var>b</var> <var>a</var></dt>
|
|
<dd><p>Exchange the top two items on the stack.
|
|
</p>
|
|
</dd>
|
|
<dt><code>pop</code> (0x29): <var>a</var> =></dt>
|
|
<dd><p>Discard the top value on the stack.
|
|
</p>
|
|
</dd>
|
|
<dt><code>pick</code> (0x32) <var>n</var>: <var>a</var> … <var>b</var> => <var>a</var> … <var>b</var> <var>a</var></dt>
|
|
<dd><p>Duplicate an item from the stack and push it on the top of the stack.
|
|
<var>n</var>, a single byte, indicates the stack item to copy. If <var>n</var>
|
|
is zero, this is the same as <code>dup</code>; if <var>n</var> is one, it copies
|
|
the item under the top item, etc. If <var>n</var> exceeds the number of
|
|
items on the stack, terminate with an error.
|
|
</p>
|
|
</dd>
|
|
<dt><code>rot</code> (0x33): <var>a</var> <var>b</var> <var>c</var> => <var>c</var> <var>a</var> <var>b</var></dt>
|
|
<dd><p>Rotate the top three items on the stack. The top item (c) becomes the third
|
|
item, the next-to-top item (b) becomes the top item and the third item (a) from
|
|
the top becomes the next-to-top item.
|
|
</p>
|
|
</dd>
|
|
<dt><code>if_goto</code> (0x20) <var>offset</var>: <var>a</var> ⇒</dt>
|
|
<dd><p>Pop an integer off the stack; if it is non-zero, branch to the given
|
|
offset in the bytecode string. Otherwise, continue to the next
|
|
instruction in the bytecode stream. In other words, if <var>a</var> is
|
|
non-zero, set the <code>pc</code> register to <code>start</code> + <var>offset</var>.
|
|
Thus, an offset of zero denotes the beginning of the expression.
|
|
</p>
|
|
<p>The <var>offset</var> is stored as a sixteen-bit unsigned value, stored
|
|
immediately following the <code>if_goto</code> bytecode. It is always stored
|
|
most significant byte first, regardless of the target’s normal
|
|
endianness. The offset is not guaranteed to fall at any particular
|
|
alignment within the bytecode stream; thus, on machines where fetching a
|
|
16-bit on an unaligned address raises an exception, you should fetch the
|
|
offset one byte at a time.
|
|
</p>
|
|
</dd>
|
|
<dt><code>goto</code> (0x21) <var>offset</var>: ⇒</dt>
|
|
<dd><p>Branch unconditionally to <var>offset</var>; in other words, set the
|
|
<code>pc</code> register to <code>start</code> + <var>offset</var>.
|
|
</p>
|
|
<p>The offset is stored in the same way as for the <code>if_goto</code> bytecode.
|
|
</p>
|
|
</dd>
|
|
<dt><code>const8</code> (0x22) <var>n</var>: ⇒ <var>n</var></dt>
|
|
<dt><code>const16</code> (0x23) <var>n</var>: ⇒ <var>n</var></dt>
|
|
<dt><code>const32</code> (0x24) <var>n</var>: ⇒ <var>n</var></dt>
|
|
<dt><code>const64</code> (0x25) <var>n</var>: ⇒ <var>n</var></dt>
|
|
<dd><p>Push the integer constant <var>n</var> on the stack, without sign extension.
|
|
To produce a small negative value, push a small twos-complement value,
|
|
and then sign-extend it using the <code>ext</code> bytecode.
|
|
</p>
|
|
<p>The constant <var>n</var> is stored in the appropriate number of bytes
|
|
following the <code>const</code><var>b</var> bytecode. The constant <var>n</var> is
|
|
always stored most significant byte first, regardless of the target’s
|
|
normal endianness. The constant is not guaranteed to fall at any
|
|
particular alignment within the bytecode stream; thus, on machines where
|
|
fetching a 16-bit on an unaligned address raises an exception, you
|
|
should fetch <var>n</var> one byte at a time.
|
|
</p>
|
|
</dd>
|
|
<dt><code>reg</code> (0x26) <var>n</var>: ⇒ <var>a</var></dt>
|
|
<dd><p>Push the value of register number <var>n</var>, without sign extension. The
|
|
registers are numbered following GDB’s conventions.
|
|
</p>
|
|
<p>The register number <var>n</var> is encoded as a 16-bit unsigned integer
|
|
immediately following the <code>reg</code> bytecode. It is always stored most
|
|
significant byte first, regardless of the target’s normal endianness.
|
|
The register number is not guaranteed to fall at any particular
|
|
alignment within the bytecode stream; thus, on machines where fetching a
|
|
16-bit on an unaligned address raises an exception, you should fetch the
|
|
register number one byte at a time.
|
|
</p>
|
|
</dd>
|
|
<dt><code>getv</code> (0x2c) <var>n</var>: ⇒ <var>v</var></dt>
|
|
<dd><p>Push the value of trace state variable number <var>n</var>, without sign
|
|
extension.
|
|
</p>
|
|
<p>The variable number <var>n</var> is encoded as a 16-bit unsigned integer
|
|
immediately following the <code>getv</code> bytecode. It is always stored most
|
|
significant byte first, regardless of the target’s normal endianness.
|
|
The variable number is not guaranteed to fall at any particular
|
|
alignment within the bytecode stream; thus, on machines where fetching a
|
|
16-bit on an unaligned address raises an exception, you should fetch the
|
|
register number one byte at a time.
|
|
</p>
|
|
</dd>
|
|
<dt><code>setv</code> (0x2d) <var>n</var>: <var>v</var> ⇒ <var>v</var></dt>
|
|
<dd><p>Set trace state variable number <var>n</var> to the value found on the top
|
|
of the stack. The stack is unchanged, so that the value is readily
|
|
available if the assignment is part of a larger expression. The
|
|
handling of <var>n</var> is as described for <code>getv</code>.
|
|
</p>
|
|
</dd>
|
|
<dt><code>trace</code> (0x0c): <var>addr</var> <var>size</var> ⇒</dt>
|
|
<dd><p>Record the contents of the <var>size</var> bytes at <var>addr</var> in a trace
|
|
buffer, for later retrieval by GDB.
|
|
</p>
|
|
</dd>
|
|
<dt><code>trace_quick</code> (0x0d) <var>size</var>: <var>addr</var> ⇒ <var>addr</var></dt>
|
|
<dd><p>Record the contents of the <var>size</var> bytes at <var>addr</var> in a trace
|
|
buffer, for later retrieval by GDB. <var>size</var> is a single byte
|
|
unsigned integer following the <code>trace</code> opcode.
|
|
</p>
|
|
<p>This bytecode is equivalent to the sequence <code>dup const8 <var>size</var>
|
|
trace</code>, but we provide it anyway to save space in bytecode strings.
|
|
</p>
|
|
</dd>
|
|
<dt><code>trace16</code> (0x30) <var>size</var>: <var>addr</var> ⇒ <var>addr</var></dt>
|
|
<dd><p>Identical to trace_quick, except that <var>size</var> is a 16-bit big-endian
|
|
unsigned integer, not a single byte. This should probably have been
|
|
named <code>trace_quick16</code>, for consistency.
|
|
</p>
|
|
</dd>
|
|
<dt><code>tracev</code> (0x2e) <var>n</var>: ⇒ <var>a</var></dt>
|
|
<dd><p>Record the value of trace state variable number <var>n</var> in the trace
|
|
buffer. The handling of <var>n</var> is as described for <code>getv</code>.
|
|
</p>
|
|
</dd>
|
|
<dt><code>tracenz</code> (0x2f) <var>addr</var> <var>size</var> ⇒</dt>
|
|
<dd><p>Record the bytes at <var>addr</var> in a trace buffer, for later retrieval
|
|
by GDB. Stop at either the first zero byte, or when <var>size</var> bytes
|
|
have been recorded, whichever occurs first.
|
|
</p>
|
|
</dd>
|
|
<dt><code>printf</code> (0x34) <var>numargs</var> <var>string</var> ⇒</dt>
|
|
<dd><p>Do a formatted print, in the style of the C function <code>printf</code>).
|
|
The value of <var>numargs</var> is the number of arguments to expect on the
|
|
stack, while <var>string</var> is the format string, prefixed with a
|
|
two-byte length. The last byte of the string must be zero, and is
|
|
included in the length. The format string includes escaped sequences
|
|
just as it appears in C source, so for instance the format string
|
|
<code>"\t%d\n"</code> is six characters long, and the output will consist of
|
|
a tab character, a decimal number, and a newline. At the top of the
|
|
stack, above the values to be printed, this bytecode will pop a
|
|
“function” and “channel”. If the function is nonzero, then the
|
|
target may treat it as a function and call it, passing the channel as
|
|
a first argument, as with the C function <code>fprintf</code>. If the
|
|
function is zero, then the target may simply call a standard formatted
|
|
print function of its choice. In all, this bytecode pops 2 +
|
|
<var>numargs</var> stack elements, and pushes nothing.
|
|
</p>
|
|
</dd>
|
|
<dt><code>end</code> (0x27): ⇒</dt>
|
|
<dd><p>Stop executing bytecode; the result should be the top element of the
|
|
stack. If the purpose of the expression was to compute an lvalue or a
|
|
range of memory, then the next-to-top of the stack is the lvalue’s
|
|
address, and the top of the stack is the lvalue’s size, in bytes.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
|
|
<hr>
|
|
<div class="header">
|
|
<p>
|
|
Next: <a href="Using-Agent-Expressions.html#Using-Agent-Expressions" accesskey="n" rel="next">Using Agent Expressions</a>, Previous: <a href="General-Bytecode-Design.html#General-Bytecode-Design" accesskey="p" rel="prev">General Bytecode Design</a>, Up: <a href="Agent-Expressions.html#Agent-Expressions" accesskey="u" rel="up">Agent Expressions</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|