7

I'm looking for a simple way to draw a stack. I know about drawstack.sty. I actually love the stacks produced by this package but the size is way too big as I'm using IEEEtran for my paper. The stack should use as less space as possible (i.e. fit the text size). This answer produces the desired result but I'm looking for a way to additionally draw pointers and comments (see the mockup below). I'm absolutely new to TikZ and therefore have no idea how to achieve this.

enter image description here

8

Using tikz \matrix and some styles defined later in this answer you can code your stack like this:

\begin{tikzpicture}
  \matrix [memory] {
        &           n/sh     \\
        & |(bi)|    //bi     \\
        & |(cmd)|   cmd      \\
   blub & |(sys)|   \&system \\
};
\node[pointer, right=2ex of sys] (esp) {esp};

\draw[->] (esp) -- (sys);
\draw[->] (cmd.east) to[out=-10,in=10] (bi.east);
\end{tikzpicture}

Note how simple is the syntax. The stack is basically a matrix with two columns. The first one is for labels or addresses, the second one are the contents. Each cell can have a name with the syntax |(name)|. Those names can be used later to draw arrows, pointers, etc. The result is:

Simple Stack

You can also give it other attributes. For example, putting |[!!]| in a cell marks it as important, and it gets highlighted. You can mark a cell as |[break above]| to get a wavy border that suggest that the memory continues. As in the following examples:

\begin{tikzpicture}
  \matrix [memory] {
        & |[break above]| \ldots   \\
        &                 n/sh     \\
        & |(bi)|          //bi     \\
        & |(cmd)|         cmd      \\
   blub & |[!!] (sys)|    \&system \\
};
\node[pointer, right=2ex of sys] (esp) {esp};
\draw[->] (esp) -- (sys);
\draw[->] (cmd.east) to[out=-10,in=10] (bi.east);
\end{tikzpicture}

Which produces:

Another example

Now, the promised code which defines those styles:

\usetikzlibrary{shapes.symbols,matrix, positioning}
\tikzset{
   memory/.style={
        matrix of nodes, name=M,
        every node/.append style={
               font=\tt, outer xsep=.4ex,
               anchor=base},
        column 2/.append style={
               every node/.append style=
                    {draw,fill=white, 
                     minimum width=#1, 
                     minimum height=1.5em}
                }, 
          row sep=-.4pt,
       },
   memory/.default=1.6cm,
   break above/.style={shape=tape, tape bend top=in and out, tape bend bottom=none},
   break below/.style={shape=tape, tape bend top=none, tape bend bottom=in and out},
   !!/.style={fill=green!20},
   pointer/.style = {font=\tt, anchor=base, inner sep=2pt},
}

Note that the style memory accepts one parameter which is the minimum width of each cell. You can then write \matrix[memory=1cm] for example. The default is 1.6cm. Note however that wider cells will use the required width and thus "break" the figure homogeneity. If you have wide cells, you'll have to adjust the value of the memory parameter to the width ot that wide cells.

|improve this answer|||||
  • 1
    +1 for making it minimal by not adding the preamble! – user11232 Jul 5 '13 at 22:42
  • Thanks! I prefer your answer because it is more intuitive to write. Nevertheless it would be nice if the space between stack and pointer was removed and if the cmd-pointer would bend more. I guess both can be achieved with "xshift" and "looseness" but I don't know where to write it best (to keep the easy syntax). – Propantriol Jul 6 '13 at 9:35
  • @Propantriol: to reduce the space between stack and pointer, just set outer xsep to a smaller value (e.g. 0). To increase the bend of the cmd-pointer, you can use the ..controls ($(cmd.east)+(10pt,2pt)$) and ($(bi.east)+(10pt,-2pt)$).. syntax instead of to[out=-10,in=10] (if you do this, the calc library needs to be loaded: \usetikzlibrary{calc}) – Herr K. Jul 6 '13 at 15:33
8

Is this what you want?

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart,calc}
\begin{document}

% From Alan Munn's answer http://tex.stackexchange.com/a/26373/18228
\begin{tikzpicture}[stack/.style={rectangle split, rectangle split parts=#1,draw, anchor=center}]
\node(s)[stack=4]  {
                 n/sh     % text
\nodepart{two}   //bi     % two
\nodepart{three} cmd      % three
\nodepart{four}  \&system % four
};

% Adding comments and pointers
\node[left=8pt] at (s.four west){blub};
\draw[<-,>=stealth](s.four east)--+(15pt,0) node[anchor=mid west]{esp};
\draw[->,>=stealth](s.three east) .. controls ($(s.two split)+(40pt,-5pt)$) 
  and ($(s.two split)+(40pt,5pt)$) .. (s.two east);

\end{tikzpicture}

\end{document}

enter image description here


Explanation

The key stack defines a multipart node, and it has several pre-defined anchors, as is shown in the picture below from the TikZ/PGF manual:

enter image description here

Now all you need is to place your comments and pointers relative to the correct anchor using \draw and \node from TikZ.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.