目录

用latex画出源代码与其汇编代码的关系图

最近在看《程序员的自我修养》,看到静态链接这一章,看到elf文件的内存布局。由于纸质书的限制,经常看到后面的汇编,就忘了前面的源代码。所以尝试用画图的形式记录下来,一来加深记忆,二来使其更加明晰。当然最简单的方式就是分别截两个图,然后画个箭头就行了,但尝试下来,清晰度感人,而后又尝试了adobe illustrator,也不尽如人意。偶然在知乎看到这个帖子,感觉是我想要的,于是按照这个教程装上了texlive和vscode(上次用texlive还是大学时写论文用到),一番Google后又搜到这个教程,应该可行。先记录下,有时间继续更新。

初步效果:

https://raw.githubusercontent.com/boatrainlsz/my-image-hosting/main/obj_file_layout.jpg
初步效果

latex代码:

\documentclass[border={35pt 10pt 150pt 60pt},svgnames]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning, calc, matrix, arrows.meta}
\usepackage{listings}
\usepackage{parcolumns}

\lstset{%
  frame            = tb,    % draw frame at top and bottom of code block
  tabsize          = 1,     % tab space width
  numbers          = left,  % display line numbers on the left
  framesep         = 3pt,   % expand outward
  framerule        = 0.4pt, % expand outward 
  commentstyle     = \color{Green},      % comment color
  keywordstyle     = \color{blue},       % keyword color
  stringstyle      = \color{DarkRed},    % string color
  backgroundcolor  = \color{WhiteSmoke}, % backgroundcolor color
  showstringspaces = false,              % do not mark spaces in strings
  breaklines=true,
  postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
}
\begin{document}
\begin{minipage}[t]{1.2\linewidth}
\begin{lstlisting}[language = C, numbers = none, escapechar = !,
    basicstyle = \ttfamily\bfseries, linewidth = 1.2\linewidth]
    int printf!
   \tikz[remember picture] \node [] (printf) {};!(const char *format, ...);

    int global_init_var = !\tikz[remember picture] \node [] (global_init_var) {};!84;
    int global_uninit_var;
    
    void func1(int i) {
        printf(!\tikz[remember picture] \node [] (placeholder) {};!"%d\n", i);
    }
    
    int main(void) {
        static int static_var = !\tikz[remember picture] \node [] (static_var) {};!85;
        static int static_var2;
        int a = 1;
        int b;
        func1(static_var + static_var2 + a + b);
        return a;
    }
\end{lstlisting}
\end{minipage}
\qquad
\begin{minipage}[t]{1.2\linewidth}
\begin{lstlisting}[numbers = none, escapechar = !,
  basicstyle = \ttfamily\bfseries, linewidth = 1.4\linewidth]
  main.o:     file format elf64-x86-64

Contents of section .text:
 0000 f30f1efa 554889e5 4883ec10 897dfc8b
 0010 45fc89c6 488d3d00 000000b8 00000000
 0020 e8000000 0090c9c3 f30f1efa 554889e5
 0030 4883ec10 c745f801 0000008b 15000000
 0040 008b0500 00000001 c28b45f8 01c28b45
 0050 fc01d089 c7e80000 00008b45 f8c9c3  
Contents of section .data:
 0000 !\tikz[remember picture] \node [] (global_init_var_hex) {};!54000000 !\tikz[remember picture] \node [] (static_var_hex) {};!55000000                  
Contents of section .rodata:
 0000 !\tikz[remember picture] \node [] (placeholder_hex) {};!25640a00                           
......

Disassembly of section .text:

0000000000000000 <func1>:
   0:   f3 0f 1e fa             endbr64
   4:   55                      push   %rbp
   5:   48 89 e5                mov    %rsp,%rbp
   8:   48 83 ec 10             sub    $0x10,%rsp
   c:   89 7d fc                mov    %edi,-0x4(%rbp)
   f:   8b 45 fc                mov    -0x4(%rbp),%eax
  12:   89 c6                   mov    %eax,%esi
  14:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # 1b <func1+0x1b>
  1b:   b8 00 00 00 00          mov    $0x0,%eax
  20:   e8 00 00 00 00          call   25 <func1+0x25>
  25:   90                      nop
  26:   c9                      leave
  27:   c3                      ret

0000000000000028 <main>:
  28:   f3 0f 1e fa             endbr64
  2c:   55                      push   %rbp
  2d:   48 89 e5                mov    %rsp,%rbp
  30:   48 83 ec 10             sub    $0x10,%rsp
  34:   c7 45 f8 01 00 00 00    movl   $0x1,-0x8(%rbp)
  3b:   8b 15 00 00 00 00       mov    0x0(%rip),%edx        # 41 <main+0x19>
  41:   8b 05 00 00 00 00       mov    0x0(%rip),%eax        # 47 <main+0x1f>
  47:   01 c2                   add    %eax,%edx
  49:   8b 45 f8                mov    -0x8(%rbp),%eax
  4c:   01 c2                   add    %eax,%edx
  4e:   8b 45 fc                mov    -0x4(%rbp),%eax
  51:   01 d0                   add    %edx,%eax
  53:   89 c7                   mov    %eax,%edi
  55:   e8 00 00 00 00          call   5a <main+0x32>
  5a:   8b 45 f8                mov    -0x8(%rbp),%eax
  5d:   c9                      leave
  5e:   c3                      ret
\end{lstlisting}
\end{minipage}

\begin{tikzpicture}[remember picture, overlay,
    every node/.append style = { align = center, minimum height = 10pt,
                                 font = \bfseries, fill= green!20},
                  text width = 2.5cm ]
\draw[->,red,line width=1pt] (global_init_var) edge [in=195, out=-30] (global_init_var_hex);
\draw[->,blue,line width=1pt] (static_var) edge [in=195, out=-30] (static_var_hex);
\draw[->,purple,line width=1pt] (placeholder) edge [in=195, out=-20] (placeholder_hex);

\end{tikzpicture} 
\end{document}

参考资料:

https://stuff.mit.edu/afs/athena/contrib/tex-contrib/beamer/pgf-1.01/doc/generic/pgf/version-for-tex4ht/en/pgfmanualse8.html

https://www.overleaf.com/learn/latex/TikZ_package

https://github.com/anvithks/hugo-embed-pdf-shortcode#setup

https://tex.stackexchange.com/questions/222991/formatting-columns-with-multicols-and-lstlisting

https://stackoverflow.com/questions/6605006/convert-pdf-to-image-with-high-resolution