the 39.7-kilobyte turbo pascal executable doesn't include the (modest) pascal runtime library, because it is itself written in assembly, not in pascal. awk, being an interpreter, does have to include the runtime library in the same executable as the parser. awk is also written in c rather than assembly, and moreover using lex and yacc; lex compiles the lexer into a deterministic automaton written in c for speed, and all of this is compiled with pcc, whose optimizations were relatively weak by today's standards
i haven't compiled version 7 myself so i don't have a clear idea of how big it is
a slight correction to my above comment! on running `file *` in bin/, i see, among other things
at: PDP-11 pure executable
awk: PDP-11 separate I&D executable
bas: PDP-11 pure executable
basename: PDP-11 pure executable
bc: PDP-11 pure executable
if i understand correctly, this means that this awk executable is built with what we used to call the 'small memory model' on the 8088, using separate instruction and data segments. that way, awk could have data stored at the same address as executable code, so you had 64 kibibytes available for just the data. you didn't have to squinch your awk program and all its data into the 65-46 = 19 kilobytes left over after the awk executable was loaded
this, in effect, allows you 128 kilobytes for the functionality of your program: when you call an awk builtin function (usr/src/cmd/awk/proc.c lists seven named functions: substr, sindex, sprintf, printf, print, split, and instat) you're invoking code in the instruction segment, while the logic of your interpreted code shares the data segment with the data you're manipulating (strings or arrays or whatever)
so it's at least misleading that i said it 'ran in the pdp-11's 64k address space'
not all pdp-11s supported separate instruction and data segments (i think the more expensive pdp-11/45 did, but the pdp-11/40 and pdp-11/20 didn't) and most of the 7th edition executables didn't require that. but awk, adb, dcheck, dd, fgrep, icheck, lex, ncheck, refer, restor, sort, tar, tbl, uucp, uulog, uux, and yacc did. i'm not sure how you were supposed to run a unix system without dd, icheck, tar, uucp, restor, or adb (sdb and dbx didn't exist), so i think maybe at this point they had given up on supporting the smaller models