Create an ASCII-to-hex table for Mark Watney Inspired by this SciFi.SE question.

Background (with minor spoiler):

 In the movie The Martian, protagonist Mark Watney uses an ASCII table to look up hexadecimal values of ASCII characters so he can attempt to communicate back to Earth.*

Challenge
With no input, output the following ASCII table exactly like this:
Dec Hex    Dec Hex    Dec Hex  Dec Hex  Dec Hex  Dec Hex   Dec Hex   Dec Hex  
  0 00 NUL  16 10 DLE  32 20    48 30 0  64 40 @  80 50 P   96 60 `  112 70 p
  1 01 SOH  17 11 DC1  33 21 !  49 31 1  65 41 A  81 51 Q   97 61 a  113 71 q
  2 02 STX  18 12 DC2  34 22 &quot;  50 32 2  66 42 B  82 52 R   98 62 b  114 72 r
  3 03 ETX  19 13 DC3  35 23 #  51 33 3  67 43 C  83 53 S   99 63 c  115 73 s
  4 04 EOT  20 14 DC4  36 24 $  52 34 4  68 44 D  84 54 T  100 64 d  116 74 t
  5 05 ENQ  21 15 NAK  37 25 %  53 35 5  69 45 E  85 55 U  101 65 e  117 75 u
  6 06 ACK  22 16 SYN  38 26 &amp;  54 36 6  70 46 F  86 56 V  102 66 f  118 76 v
  7 07 BEL  23 17 ETB  39 27 '  55 37 7  71 47 G  87 57 W  103 67 g  119 77 w
  8 08 BS   24 18 CAN  40 28 (  56 38 8  72 48 H  88 58 X  104 68 h  120 78 x
  9 09 HT   25 19 EM   41 29 )  57 39 9  73 49 I  89 59 Y  105 69 i  121 79 y
 10 0A LF   26 1A SUB  42 2A *  58 3A :  74 4A J  90 5A Z  106 6A j  122 7A z
 11 0B VT   27 1B ESC  43 2B +  59 3B ;  75 4B K  91 5B [  107 6B k  123 7B {
 12 0C FF   28 1C FS   44 2C ,  60 3C &lt;  76 4C L  92 5C \  108 6C l  124 7C |
 13 0D CR   29 1D GS   45 2D -  61 3D =  77 4D M  93 5D ]  109 6D m  125 7D }
 14 0E SO   30 1E RS   46 2E .  62 3E &gt;  78 4E N  94 5E ^  110 6E n  126 7E ~
 15 0F SI   31 1F US   47 2F /  63 3F ?  79 4F O  95 5F _  111 6F o  127 7F DEL

The final newline is optional.  With the newline, the md5 of the output is 58824a1dd7264c0410eb4d727aec54e1.  Without, it is 41b6ecde6a3a1324be4836871d8354fe.
In case it helps, this is the output from the ascii Linux command with the usage info at the top chopped off.  You can recreate this on Ubuntu as follows:
sudo apt-get install ascii
ascii | tail -n+7

You may not use the ascii utility (or similar) in your answers.
Because ASCII characters are small Enough with this silly meme already!

I am aware this is similar to Print the ASCII table, but I believe the formatting of the output in this question is significantly more complex and warrants a different question.

*Note, I have not yet seen this movie.
JavaScript (ES6), 323 332 353

Edit I managed to shorten this a bit
Step 1, believe it or not, using an array of 16 chars is shorter than toString + toUpperCase
Step 2, fiddling around to use .map instead of for, so that I can transform it all to a single expression function, avoding console.log and/or return.

Edit 2 Moved DEL at place 0, idea borrowed from Cole Cameron

H=x=&gt;(x=[...'0123456789ABCDEF']).map((d,r)=&gt;x[S='slice'](0,8).map(c=&gt;(o+=`   ${w=c*16+r} ${c+d} `[S](-z)+("DELNULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ".substr((w+1&amp;127)*3,3)||String.fromCharCode(w)),z=c&lt;5?8:9,'Dec Hex   '[S](0,c&lt;2?z+2:z)),o+=`
`,z=7).join` `,o='')[0]+o


MD5: 41B6ECDE6A3A1324BE4836871D8354FE

Pixel perfect, I'd say

LESS GOLFED

H=x=&gt;(
  x=[...'0123456789ABCDEF'],
  a="DELNULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ",
  o='', // the string o will contain the body (16 rows)
  x.map((d,r)=&gt; ( // main loop, r is thr row number, d is the second hex digit to print
    o+=`\n`, z=7,
    x.slice(0,8).map(c=&gt; // loop on 8 columns, c is both column number and digit to print
      (
        // append the column to o
        o += `   ${w=c*16+r} ${c+d} `.slice(-z) + (a.substr((w+1&amp;127)*3,3)||String.fromCharCode(w)), 
        z=c&lt;5?8:9, // adjust the column size
        'Dec Hex   '.slice(0,c&lt;2?z+2:z) // column head, right size
      ) // the .map result is the 8 columns heading
    ).join` ` // join the heading in a single string
  ))[0] // any element of the result map is the heading
  + o // concatenate the body
)


Test



H=x=&gt;(x=[...'0123456789ABCDEF']).map((d,r)=&gt;x[S='slice'](0,8).map(c=&gt;(o+=`   ${w=c*16+r} ${c+d} `[S](-z)+("DELNULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ".substr((w+1&amp;127)*3,3)||String.fromCharCode(w)),z=c&lt;5?8:9,'Dec Hex   '[S](0,c&lt;2?z+2:z)),o+=`
`,z=7).join` `,o='')[0]+o

/* TEST */ 
console.log=x=&gt;O.textContent=x

console.log(H())
&lt;pre id=O&gt;&lt;/pre&gt;